Rename mfxkit to agent

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>
This commit is contained in:
Darko Draskovic
2023-03-27 16:37:52 +02:00
parent 6ec53d074f
commit ad60e95736
26 changed files with 62 additions and 498 deletions
+17 -17
View File
@@ -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
@@ -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
+6 -6
View File
@@ -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
}
+18 -18
View File
@@ -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)
}
-1
View File
@@ -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
-5
View File
@@ -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=
-39
View File
@@ -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)
}
-31
View File
@@ -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
}
}
-7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
-5
View File
@@ -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