mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-23 04:10:25 +00:00
Rename mfxkit to agent
Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Mfxkit
|
||||
# Agent
|
||||
|
||||
Mfxkit service provides a barebones HTTP API and Service interface implementation for development of a core Mainflux service.
|
||||
Agent service provides a barebones HTTP API and Service interface implementation for development of a core Mainflux service.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -8,12 +8,12 @@ The service is configured using the environment variables from the following tab
|
||||
|
||||
| Variable | Description | Default |
|
||||
|-----------------------|---------------------------------------------------------|---------|
|
||||
| MF_MFXKIT_LOG_LEVEL | Log level for mfxkit service (debug, info, warn, error) | error |
|
||||
| MF_MFXKIT_HTTP_PORT | Mfxkit service HTTP port | 9021 |
|
||||
| MF_MFXKIT_SERVER_CERT | Path to server certificate in pem format | |
|
||||
| MF_MFXKIT_SERVER_KEY | Path to server key in pem format | |
|
||||
| MF_AGENT_LOG_LEVEL | Log level for agent service (debug, info, warn, error) | error |
|
||||
| MF_AGENT_HTTP_PORT | Agent service HTTP port | 9021 |
|
||||
| MF_AGENT_SERVER_CERT | Path to server certificate in pem format | |
|
||||
| MF_AGENT_SERVER_KEY | Path to server key in pem format | |
|
||||
| MF_JAEGER_URL | Jaeger server URL | |
|
||||
| MF_MFXKIT_SECRET | Mfxkit service secret | secret |
|
||||
| MF_AGENT_SECRET | Agent service secret | secret |
|
||||
|
||||
## Deployment
|
||||
|
||||
@@ -22,17 +22,17 @@ The service is distributed as a Docker container. The following snippet provides
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
mfxkit:
|
||||
image: mainflux/mfxkit:[version]
|
||||
agent:
|
||||
image: ultravioletrs/agent:[version]
|
||||
container_name: [instance name]
|
||||
ports:
|
||||
- [host machine port]:[configured HTTP port]
|
||||
environment:
|
||||
MF_MFXKIT_LOG_LEVEL: [Kit log level]
|
||||
MF_MFXKIT_HTTP_PORT: [Service HTTP port]
|
||||
MF_MFXKIT_SERVER_CERT: [String path to server cert in pem format]
|
||||
MF_MFXKIT_SERVER_KEY: [String path to server key in pem format]
|
||||
MF_MFXKIT_SECRET: [Mfxkit service secret]
|
||||
MF_AGENT_LOG_LEVEL: [Kit log level]
|
||||
MF_AGENT_HTTP_PORT: [Service HTTP port]
|
||||
MF_AGENT_SERVER_CERT: [String path to server cert in pem format]
|
||||
MF_AGENT_SERVER_KEY: [String path to server key in pem format]
|
||||
MF_AGENT_SECRET: [Agent service secret]
|
||||
MF_JAEGER_URL: [Jaeger server URL]
|
||||
```
|
||||
|
||||
@@ -44,14 +44,14 @@ go get github.com/mainflux/mainflux
|
||||
|
||||
cd $GOPATH/src/github.com/mainflux/mainflux
|
||||
|
||||
# compile the mfxkit
|
||||
make mfxkit
|
||||
# compile the agent
|
||||
make agent
|
||||
|
||||
# copy binary to bin
|
||||
make install
|
||||
|
||||
# set the environment variables and run the service
|
||||
MF_MFXKIT_LOG_LEVEL=[Kit log level] MF_MFXKIT_HTTP_PORT=[Service HTTP port] MF_MFXKIT_SERVER_CERT: [String path to server cert in pem format] MF_MFXKIT_SERVER_KEY: [String path to server key in pem format] MF_JAEGER_URL=[Jaeger server URL] MF_MFXKIT_SECRET: [Mfxkit service secret] $GOBIN/mainflux-kit
|
||||
MF_AGENT_LOG_LEVEL=[Kit log level] MF_AGENT_HTTP_PORT=[Service HTTP port] MF_AGENT_SERVER_CERT: [String path to server cert in pem format] MF_AGENT_SERVER_KEY: [String path to server key in pem format] MF_JAEGER_URL=[Jaeger server URL] MF_AGENT_SECRET: [Agent service secret] $GOBIN/mainflux-kit
|
||||
```
|
||||
|
||||
## Usage
|
||||
+2
-2
@@ -7,10 +7,10 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
agent "github.com/ultravioletrs/agent/agent"
|
||||
)
|
||||
|
||||
func pingEndpoint(svc mfxkit.Service) endpoint.Endpoint {
|
||||
func pingEndpoint(svc agent.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(pingReq)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package http
|
||||
|
||||
import "github.com/mainflux/mfxkit/mfxkit"
|
||||
import agent "github.com/ultravioletrs/agent/agent"
|
||||
|
||||
type apiReq interface {
|
||||
validate() error
|
||||
@@ -15,7 +15,7 @@ type pingReq struct {
|
||||
|
||||
func (req pingReq) validate() error {
|
||||
if req.Secret == "" {
|
||||
return mfxkit.ErrMalformedEntity
|
||||
return agent.ErrMalformedEntity
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -16,9 +16,9 @@ import (
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"github.com/go-zoo/bone"
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
agent "github.com/ultravioletrs/agent/agent"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -31,14 +31,14 @@ var (
|
||||
)
|
||||
|
||||
// MakeHandler returns a HTTP handler for API endpoints.
|
||||
func MakeHandler(tracer opentracing.Tracer, svc mfxkit.Service) http.Handler {
|
||||
func MakeHandler(tracer opentracing.Tracer, svc agent.Service) http.Handler {
|
||||
opts := []kithttp.ServerOption{
|
||||
kithttp.ServerErrorEncoder(encodeError),
|
||||
}
|
||||
|
||||
r := bone.New()
|
||||
|
||||
r.Post("/mfxkit", kithttp.NewServer(
|
||||
r.Post("/agent", kithttp.NewServer(
|
||||
kitot.TraceServer(tracer, "ping")(pingEndpoint(svc)),
|
||||
decodePing,
|
||||
encodeResponse,
|
||||
@@ -86,9 +86,9 @@ func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
switch err {
|
||||
case mfxkit.ErrMalformedEntity:
|
||||
case agent.ErrMalformedEntity:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case mfxkit.ErrUnauthorizedAccess:
|
||||
case agent.ErrUnauthorizedAccess:
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
case errUnsupportedContentType:
|
||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !test
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
@@ -10,18 +11,18 @@ import (
|
||||
"time"
|
||||
|
||||
log "github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
"github.com/ultravioletrs/agent/agent"
|
||||
)
|
||||
|
||||
var _ mfxkit.Service = (*loggingMiddleware)(nil)
|
||||
var _ agent.Service = (*loggingMiddleware)(nil)
|
||||
|
||||
type loggingMiddleware struct {
|
||||
logger log.Logger
|
||||
svc mfxkit.Service
|
||||
svc agent.Service
|
||||
}
|
||||
|
||||
// LoggingMiddleware adds logging facilities to the core service.
|
||||
func LoggingMiddleware(svc mfxkit.Service, logger log.Logger) mfxkit.Service {
|
||||
func LoggingMiddleware(svc agent.Service, logger log.Logger) agent.Service {
|
||||
return &loggingMiddleware{logger, svc}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//go:build !test
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
@@ -9,20 +10,20 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/kit/metrics"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
"github.com/ultravioletrs/agent/agent"
|
||||
)
|
||||
|
||||
var _ mfxkit.Service = (*metricsMiddleware)(nil)
|
||||
var _ agent.Service = (*metricsMiddleware)(nil)
|
||||
|
||||
type metricsMiddleware struct {
|
||||
counter metrics.Counter
|
||||
latency metrics.Histogram
|
||||
svc mfxkit.Service
|
||||
svc agent.Service
|
||||
}
|
||||
|
||||
// MetricsMiddleware instruments core service by tracking request count and
|
||||
// latency.
|
||||
func MetricsMiddleware(svc mfxkit.Service, counter metrics.Counter, latency metrics.Histogram) mfxkit.Service {
|
||||
func MetricsMiddleware(svc agent.Service, counter metrics.Counter, latency metrics.Histogram) agent.Service {
|
||||
return &metricsMiddleware{
|
||||
counter: counter,
|
||||
latency: latency,
|
||||
@@ -2,6 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package things contains the domain concept definitions needed to support
|
||||
// Mainflux mfxkit service functionality.
|
||||
// Mainflux agent service functionality.
|
||||
|
||||
package mfxkit
|
||||
package agent
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package mfxkit
|
||||
package agent
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -24,20 +24,20 @@ type Service interface {
|
||||
Ping(string) (string, error)
|
||||
}
|
||||
|
||||
type mfxkitService struct {
|
||||
type agentService struct {
|
||||
secret string
|
||||
}
|
||||
|
||||
var _ Service = (*mfxkitService)(nil)
|
||||
var _ Service = (*agentService)(nil)
|
||||
|
||||
// New instantiates the mfxkit service implementation.
|
||||
// New instantiates the agent service implementation.
|
||||
func New(secret string) Service {
|
||||
return &mfxkitService{
|
||||
return &agentService{
|
||||
secret: secret,
|
||||
}
|
||||
}
|
||||
|
||||
func (ks *mfxkitService) Ping(secret string) (string, error) {
|
||||
func (ks *agentService) Ping(secret string) (string, error) {
|
||||
if ks.secret != secret {
|
||||
return "", ErrUnauthorizedAccess
|
||||
}
|
||||
@@ -19,9 +19,9 @@ import (
|
||||
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
"github.com/mainflux/mfxkit/mfxkit/api"
|
||||
mfxkithttpapi "github.com/mainflux/mfxkit/mfxkit/api/mfxkit/http"
|
||||
agent "github.com/ultravioletrs/agent/agent"
|
||||
"github.com/ultravioletrs/agent/agent/api"
|
||||
agenthttpapi "github.com/ultravioletrs/agent/agent/api/agent/http"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
@@ -37,11 +37,11 @@ const (
|
||||
defServerKey = ""
|
||||
defSecret = "secret"
|
||||
|
||||
envLogLevel = "MF_MFXKIT_LOG_LEVEL"
|
||||
envHTTPPort = "MF_MFXKIT_HTTP_PORT"
|
||||
envServerCert = "MF_MFXKIT_SERVER_CERT"
|
||||
envServerKey = "MF_MFXKIT_SERVER_KEY"
|
||||
envSecret = "MF_MFXKIT_SECRET"
|
||||
envLogLevel = "MF_AGENT_LOG_LEVEL"
|
||||
envHTTPPort = "MF_AGENT_HTTP_PORT"
|
||||
envServerCert = "MF_AGENT_SERVER_CERT"
|
||||
envServerKey = "MF_AGENT_SERVER_KEY"
|
||||
envSecret = "MF_AGENT_SECRET"
|
||||
envJaegerURL = "MF_JAEGER_URL"
|
||||
)
|
||||
|
||||
@@ -64,13 +64,13 @@ func main() {
|
||||
log.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
mfxkitTracer, mfxkitCloser := initJaeger("mfxkit", cfg.jaegerURL, logger)
|
||||
defer mfxkitCloser.Close()
|
||||
agentTracer, agentCloser := initJaeger("agent", cfg.jaegerURL, logger)
|
||||
defer agentCloser.Close()
|
||||
|
||||
svc := newService(cfg.secret, logger)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
go startHTTPServer(mfxkithttpapi.MakeHandler(mfxkitTracer, svc), cfg.httpPort, cfg, logger, errs)
|
||||
go startHTTPServer(agenthttpapi.MakeHandler(agentTracer, svc), cfg.httpPort, cfg, logger, errs)
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
@@ -79,7 +79,7 @@ func main() {
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Mfxkit service terminated: %s", err))
|
||||
logger.Error(fmt.Sprintf("Agent service terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@@ -117,20 +117,20 @@ func initJaeger(svcName, url string, logger logger.Logger) (opentracing.Tracer,
|
||||
return tracer, closer
|
||||
}
|
||||
|
||||
func newService(secret string, logger logger.Logger) mfxkit.Service {
|
||||
svc := mfxkit.New(secret)
|
||||
func newService(secret string, logger logger.Logger) agent.Service {
|
||||
svc := agent.New(secret)
|
||||
|
||||
svc = api.LoggingMiddleware(svc, logger)
|
||||
svc = api.MetricsMiddleware(
|
||||
svc,
|
||||
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
||||
Namespace: "mfxkit",
|
||||
Namespace: "agent",
|
||||
Subsystem: "api",
|
||||
Name: "request_count",
|
||||
Help: "Number of requests received.",
|
||||
}, []string{"method"}),
|
||||
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
||||
Namespace: "mfxkit",
|
||||
Namespace: "agent",
|
||||
Subsystem: "api",
|
||||
Name: "request_latency_microseconds",
|
||||
Help: "Total duration of requests in microseconds.",
|
||||
@@ -143,11 +143,11 @@ func newService(secret string, logger logger.Logger) mfxkit.Service {
|
||||
func startHTTPServer(handler http.Handler, port string, cfg config, logger logger.Logger, errs chan error) {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
logger.Info(fmt.Sprintf("Mfxkit service started using https on port %s with cert %s key %s",
|
||||
logger.Info(fmt.Sprintf("Agent service started using https on port %s with cert %s key %s",
|
||||
port, cfg.serverCert, cfg.serverKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, handler)
|
||||
return
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Mfxkit service started using http on port %s", cfg.httpPort))
|
||||
logger.Info(fmt.Sprintf("Agent service started using http on port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, handler)
|
||||
}
|
||||
@@ -6,7 +6,6 @@ require (
|
||||
github.com/go-kit/kit v0.10.0
|
||||
github.com/go-zoo/bone v1.3.0
|
||||
github.com/mainflux/mainflux v0.12.0
|
||||
github.com/mainflux/mfxkit v0.0.0-20210414105055-bc327eee2816
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/prometheus/client_golang v1.11.1
|
||||
github.com/spf13/cobra v1.6.1
|
||||
|
||||
@@ -406,8 +406,6 @@ github.com/mainflux/mainflux v0.0.0-20200512161904-df6f5adff8e4/go.mod h1:2caJ68
|
||||
github.com/mainflux/mainflux v0.11.1-0.20200603183352-7f3e2c1b21ed/go.mod h1:8jwcwH3MKYgoQks9BBHq19Br25ElzW25vteZX7tWZ+w=
|
||||
github.com/mainflux/mainflux v0.12.0 h1:UcZpOlGgkXi27gMFVmppAw3Mi6gTjfA0wyUELTTcA3E=
|
||||
github.com/mainflux/mainflux v0.12.0/go.mod h1:d5L91byP5g4Y8dMzd+4LDjXuMy2oM80qg5nt5jMXN5I=
|
||||
github.com/mainflux/mfxkit v0.0.0-20210414105055-bc327eee2816 h1:P86W35Fa3ncFfCLx9Qv3ZKOVZam3CusPOMQZbuzw3ds=
|
||||
github.com/mainflux/mfxkit v0.0.0-20210414105055-bc327eee2816/go.mod h1:NOOpgtDLYRYbE3+Fs5HSyXhs/TklGmBn0+ovpQ6NmKw=
|
||||
github.com/mainflux/mproxy v0.1.3/go.mod h1:/BdaBfgye1GNCD+eat4ipFamy9IEVRH5nhZS0yEShVg=
|
||||
github.com/mainflux/mproxy v0.1.5/go.mod h1:MBLtv/RvhT8QsmXz4g3GxkRaP8PqlVqBWeqvw9QmO8k=
|
||||
github.com/mainflux/mproxy v0.1.8/go.mod h1:NnhrUDytvV4pCI5LDuet86/WrymrUaX0/x1tlUHTKhU=
|
||||
@@ -543,7 +541,6 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
|
||||
github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
|
||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
@@ -561,7 +558,6 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
@@ -842,7 +838,6 @@ golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
log "github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
)
|
||||
|
||||
var _ mfxkit.Service = (*loggingMiddleware)(nil)
|
||||
|
||||
type loggingMiddleware struct {
|
||||
logger log.Logger
|
||||
svc mfxkit.Service
|
||||
}
|
||||
|
||||
// LoggingMiddleware adds logging facilities to the core service.
|
||||
func LoggingMiddleware(svc mfxkit.Service, logger log.Logger) mfxkit.Service {
|
||||
return &loggingMiddleware{logger, svc}
|
||||
}
|
||||
|
||||
func (lm *loggingMiddleware) Ping(secret string) (response string, err error) {
|
||||
defer func(begin time.Time) {
|
||||
message := fmt.Sprintf("Method ping for secret %s took %s to complete", secret, time.Since(begin))
|
||||
if err != nil {
|
||||
lm.logger.Warn(fmt.Sprintf("%s with error: %s.", message, err))
|
||||
return
|
||||
}
|
||||
lm.logger.Info(fmt.Sprintf("%s without errors.", message))
|
||||
}(time.Now())
|
||||
|
||||
return lm.svc.Ping(secret)
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
)
|
||||
|
||||
func pingEndpoint(svc mfxkit.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(pingReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
greeting, err := svc.Ping(req.Secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := pingRes{
|
||||
Greeting: greeting,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package things contains the domain concept definitions needed to support
|
||||
// Mainflux mfxkit service functionality.
|
||||
|
||||
package mfxkit
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
# Mfxkit
|
||||
|
||||
Mfxkit service provides a barebones HTTP API and Service interface implementation for development of a core Mainflux service.
|
||||
|
||||
## Configuration
|
||||
|
||||
The service is configured using the environment variables from the following table. Note that any unset variables will be replaced with their default values.
|
||||
|
||||
| Variable | Description | Default |
|
||||
|-----------------------|---------------------------------------------------------|---------|
|
||||
| MF_MFXKIT_LOG_LEVEL | Log level for mfxkit service (debug, info, warn, error) | error |
|
||||
| MF_MFXKIT_HTTP_PORT | Mfxkit service HTTP port | 9021 |
|
||||
| MF_MFXKIT_SERVER_CERT | Path to server certificate in pem format | |
|
||||
| MF_MFXKIT_SERVER_KEY | Path to server key in pem format | |
|
||||
| MF_JAEGER_URL | Jaeger server URL | |
|
||||
| MF_MFXKIT_SECRET | Mfxkit service secret | secret |
|
||||
|
||||
## Deployment
|
||||
|
||||
The service is distributed as a Docker container. The following snippet provides a compose file template that can be used to deploy the service container locally:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
mfxkit:
|
||||
image: mainflux/mfxkit:[version]
|
||||
container_name: [instance name]
|
||||
ports:
|
||||
- [host machine port]:[configured HTTP port]
|
||||
environment:
|
||||
MF_MFXKIT_LOG_LEVEL: [Kit log level]
|
||||
MF_MFXKIT_HTTP_PORT: [Service HTTP port]
|
||||
MF_MFXKIT_SERVER_CERT: [String path to server cert in pem format]
|
||||
MF_MFXKIT_SERVER_KEY: [String path to server key in pem format]
|
||||
MF_MFXKIT_SECRET: [Mfxkit service secret]
|
||||
MF_JAEGER_URL: [Jaeger server URL]
|
||||
```
|
||||
|
||||
To start the service outside of the container, execute the following shell script:
|
||||
|
||||
```bash
|
||||
# download the latest version of the service
|
||||
go get github.com/mainflux/mainflux
|
||||
|
||||
cd $GOPATH/src/github.com/mainflux/mainflux
|
||||
|
||||
# compile the mfxkit
|
||||
make mfxkit
|
||||
|
||||
# copy binary to bin
|
||||
make install
|
||||
|
||||
# set the environment variables and run the service
|
||||
MF_MFXKIT_LOG_LEVEL=[Kit log level] MF_MFXKIT_HTTP_PORT=[Service HTTP port] MF_MFXKIT_SERVER_CERT: [String path to server cert in pem format] MF_MFXKIT_SERVER_KEY: [String path to server key in pem format] MF_JAEGER_URL=[Jaeger server URL] MF_MFXKIT_SECRET: [Mfxkit service secret] $GOBIN/mainflux-kit
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
For more information about service capabilities and its usage, please check out the [API documentation](swagger.yaml).
|
||||
|
||||
[doc]: http://mainflux.readthedocs.io
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package api contains API-related concerns: endpoint definitions, middlewares
|
||||
// and all resource representations.
|
||||
package api
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// +build !test
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/kit/metrics"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
)
|
||||
|
||||
var _ mfxkit.Service = (*metricsMiddleware)(nil)
|
||||
|
||||
type metricsMiddleware struct {
|
||||
counter metrics.Counter
|
||||
latency metrics.Histogram
|
||||
svc mfxkit.Service
|
||||
}
|
||||
|
||||
// MetricsMiddleware instruments core service by tracking request count and
|
||||
// latency.
|
||||
func MetricsMiddleware(svc mfxkit.Service, counter metrics.Counter, latency metrics.Histogram) mfxkit.Service {
|
||||
return &metricsMiddleware{
|
||||
counter: counter,
|
||||
latency: latency,
|
||||
svc: svc,
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *metricsMiddleware) Ping(secret string) (response string, err error) {
|
||||
defer func(begin time.Time) {
|
||||
ms.counter.With("method", "ping").Add(1)
|
||||
ms.latency.With("method", "ping").Observe(time.Since(begin).Seconds())
|
||||
}(time.Now())
|
||||
|
||||
return ms.svc.Ping(secret)
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package http contains implementation of kit service HTTP API.
|
||||
package http
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package http
|
||||
|
||||
import "github.com/mainflux/mfxkit/mfxkit"
|
||||
|
||||
type apiReq interface {
|
||||
validate() error
|
||||
}
|
||||
|
||||
type pingReq struct {
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
func (req pingReq) validate() error {
|
||||
if req.Secret == "" {
|
||||
return mfxkit.ErrMalformedEntity
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/mainflux/mainflux"
|
||||
)
|
||||
|
||||
var _ mainflux.Response = (*pingRes)(nil)
|
||||
|
||||
type pingRes struct {
|
||||
Greeting string `json:"greeting"`
|
||||
}
|
||||
|
||||
func (res pingRes) Code() int {
|
||||
return http.StatusOK
|
||||
}
|
||||
|
||||
func (res pingRes) Headers() map[string]string {
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
func (res pingRes) Empty() bool {
|
||||
return false
|
||||
}
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
kitot "github.com/go-kit/kit/tracing/opentracing"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"github.com/go-zoo/bone"
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mfxkit/mfxkit"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
const (
|
||||
contentType = "application/json"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnsupportedContentType = errors.New("unsupported content type")
|
||||
errInvalidQueryParams = errors.New("invalid query params")
|
||||
)
|
||||
|
||||
// MakeHandler returns a HTTP handler for API endpoints.
|
||||
func MakeHandler(tracer opentracing.Tracer, svc mfxkit.Service) http.Handler {
|
||||
opts := []kithttp.ServerOption{
|
||||
kithttp.ServerErrorEncoder(encodeError),
|
||||
}
|
||||
|
||||
r := bone.New()
|
||||
|
||||
r.Post("/mfxkit", kithttp.NewServer(
|
||||
kitot.TraceServer(tracer, "ping")(pingEndpoint(svc)),
|
||||
decodePing,
|
||||
encodeResponse,
|
||||
opts...,
|
||||
))
|
||||
|
||||
r.GetFunc("/version", mainflux.Version("things"))
|
||||
r.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func decodePing(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
if !strings.Contains(r.Header.Get("Content-Type"), contentType) {
|
||||
return nil, errUnsupportedContentType
|
||||
}
|
||||
|
||||
req := pingReq{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
if ar, ok := response.(mainflux.Response); ok {
|
||||
for k, v := range ar.Headers() {
|
||||
w.Header().Set(k, v)
|
||||
}
|
||||
|
||||
w.WriteHeader(ar.Code())
|
||||
|
||||
if ar.Empty() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
switch err {
|
||||
case mfxkit.ErrMalformedEntity:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case mfxkit.ErrUnauthorizedAccess:
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
case errUnsupportedContentType:
|
||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||
case errInvalidQueryParams:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case io.ErrUnexpectedEOF:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case io.EOF:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
default:
|
||||
switch err.(type) {
|
||||
case *json.SyntaxError:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case *json.UnmarshalTypeError:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
default:
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readUintQuery(r *http.Request, key string, def uint64) (uint64, error) {
|
||||
vals := bone.GetQuery(r, key)
|
||||
if len(vals) > 1 {
|
||||
return 0, errInvalidQueryParams
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return def, nil
|
||||
}
|
||||
|
||||
strval := vals[0]
|
||||
val, err := strconv.ParseUint(strval, 10, 64)
|
||||
if err != nil {
|
||||
return 0, errInvalidQueryParams
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func readStringQuery(r *http.Request, key string) (string, error) {
|
||||
vals := bone.GetQuery(r, key)
|
||||
if len(vals) > 1 {
|
||||
return "", errInvalidQueryParams
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return vals[0], nil
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
// Copyright (c) Mainflux
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package mfxkit
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrMalformedEntity indicates malformed entity specification (e.g.
|
||||
// invalid username or password).
|
||||
ErrMalformedEntity = errors.New("malformed entity specification")
|
||||
|
||||
// ErrUnauthorizedAccess indicates missing or invalid credentials provided
|
||||
// when accessing a protected resource.
|
||||
ErrUnauthorizedAccess = errors.New("missing or invalid credentials provided")
|
||||
)
|
||||
|
||||
// Service specifies an API that must be fullfiled by the domain service
|
||||
// implementation, and all of its decorators (e.g. logging & metrics).
|
||||
type Service interface {
|
||||
// Ping compares a given string with secret
|
||||
Ping(string) (string, error)
|
||||
}
|
||||
|
||||
type mfxkitService struct {
|
||||
secret string
|
||||
}
|
||||
|
||||
var _ Service = (*mfxkitService)(nil)
|
||||
|
||||
// New instantiates the mfxkit service implementation.
|
||||
func New(secret string) Service {
|
||||
return &mfxkitService{
|
||||
secret: secret,
|
||||
}
|
||||
}
|
||||
|
||||
func (ks *mfxkitService) Ping(secret string) (string, error) {
|
||||
if ks.secret != secret {
|
||||
return "", ErrUnauthorizedAccess
|
||||
}
|
||||
return "Hello World :)", nil
|
||||
}
|
||||
Vendored
-5
@@ -54,11 +54,6 @@ github.com/magiconair/properties
|
||||
## explicit; go 1.14
|
||||
github.com/mainflux/mainflux
|
||||
github.com/mainflux/mainflux/logger
|
||||
# github.com/mainflux/mfxkit v0.0.0-20210414105055-bc327eee2816
|
||||
## explicit; go 1.16
|
||||
github.com/mainflux/mfxkit/mfxkit
|
||||
github.com/mainflux/mfxkit/mfxkit/api
|
||||
github.com/mainflux/mfxkit/mfxkit/api/mfxkit/http
|
||||
# github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||
## explicit
|
||||
github.com/matttproud/golang_protobuf_extensions/pbutil
|
||||
|
||||
Reference in New Issue
Block a user