From bcadd7c47b235b42faa1114963dd630aaa9bc18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Borov=C4=8Danin?= Date: Tue, 27 Nov 2018 14:02:30 +0100 Subject: [PATCH] Make CoAP ping period configurable (#469) Signed-off-by: Dusan Borovcanin --- cmd/coap/main.go | 72 ++++++++++++++++++++++++++----------------- coap/README.md | 20 ++++++------ coap/api/transport.go | 9 +++--- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/cmd/coap/main.go b/cmd/coap/main.go index 127eadda..74d522a6 100644 --- a/cmd/coap/main.go +++ b/cmd/coap/main.go @@ -15,6 +15,7 @@ import ( "os/signal" "strconv" "syscall" + "time" gocoap "github.com/dustin/go-coap" kitprometheus "github.com/go-kit/kit/metrics/prometheus" @@ -32,28 +33,31 @@ import ( ) const ( - defPort = "5683" - defNatsURL = broker.DefaultURL - defThingsURL = "localhost:8181" - defLogLevel = "error" - defClientTLS = "false" - defCACerts = "" + defPort = "5683" + defNatsURL = broker.DefaultURL + defThingsURL = "localhost:8181" + defLogLevel = "error" + defClientTLS = "false" + defCACerts = "" + defPingPeriod = "12" - envPort = "MF_COAP_ADAPTER_PORT" - envNatsURL = "MF_NATS_URL" - envThingsURL = "MF_THINGS_URL" - envLogLevel = "MF_COAP_ADAPTER_LOG_LEVEL" - envClientTLS = "MF_COAP_ADAPTER_CLIENT_TLS" - envCACerts = "MF_COAP_ADAPTER_CA_CERTS" + envPort = "MF_COAP_ADAPTER_PORT" + envNatsURL = "MF_NATS_URL" + envThingsURL = "MF_THINGS_URL" + envLogLevel = "MF_COAP_ADAPTER_LOG_LEVEL" + envClientTLS = "MF_COAP_ADAPTER_CLIENT_TLS" + envCACerts = "MF_COAP_ADAPTER_CA_CERTS" + envPingPeriod = "MF_COAP_ADAPTER_PING_PERIOD" ) type config struct { - port string - natsURL string - thingsURL string - logLevel string - clientTLS bool - caCerts string + port string + natsURL string + thingsURL string + logLevel string + clientTLS bool + caCerts string + pingPeriod time.Duration } func main() { @@ -99,7 +103,7 @@ func main() { errs := make(chan error, 2) go startHTTPServer(cfg.port, logger, errs) - go startCOAPServer(cfg.port, svc, cc, respChan, logger, errs) + go startCOAPServer(cfg, svc, cc, respChan, logger, errs) go func() { c := make(chan os.Signal) @@ -117,13 +121,23 @@ func loadConfig() config { log.Fatalf("Invalid value passed for %s\n", envClientTLS) } + pp, err := strconv.ParseInt(mainflux.Env(envPingPeriod, defPingPeriod), 10, 64) + if err != nil { + log.Fatalf("Invalid value passed for %s\n", envPingPeriod) + } + + if pp < 1 || pp > 24 { + log.Fatalf("Value of %s must be between 1 and 24", envPingPeriod) + } + return config{ - thingsURL: mainflux.Env(envThingsURL, defThingsURL), - natsURL: mainflux.Env(envNatsURL, defNatsURL), - port: mainflux.Env(envPort, defPort), - logLevel: mainflux.Env(envLogLevel, defLogLevel), - clientTLS: tls, - caCerts: mainflux.Env(envCACerts, defCACerts), + thingsURL: mainflux.Env(envThingsURL, defThingsURL), + natsURL: mainflux.Env(envNatsURL, defNatsURL), + port: mainflux.Env(envPort, defPort), + logLevel: mainflux.Env(envLogLevel, defLogLevel), + clientTLS: tls, + caCerts: mainflux.Env(envCACerts, defCACerts), + pingPeriod: time.Duration(pp), } } @@ -157,8 +171,8 @@ func startHTTPServer(port string, logger logger.Logger, errs chan error) { errs <- http.ListenAndServe(p, api.MakeHTTPHandler()) } -func startCOAPServer(port string, svc coap.Service, auth mainflux.ThingsServiceClient, respChan chan<- string, l logger.Logger, errs chan error) { - p := fmt.Sprintf(":%s", port) - l.Info(fmt.Sprintf("CoAP adapter service started, exposed port %s", port)) - errs <- gocoap.ListenAndServe("udp", p, api.MakeCOAPHandler(svc, auth, l, respChan)) +func startCOAPServer(cfg config, svc coap.Service, auth mainflux.ThingsServiceClient, respChan chan<- string, l logger.Logger, errs chan error) { + p := fmt.Sprintf(":%s", cfg.port) + l.Info(fmt.Sprintf("CoAP adapter service started, exposed port %s", cfg.port)) + errs <- gocoap.ListenAndServe("udp", p, api.MakeCOAPHandler(svc, auth, l, respChan, cfg.pingPeriod)) } diff --git a/coap/README.md b/coap/README.md index de8d2830..854e9339 100644 --- a/coap/README.md +++ b/coap/README.md @@ -9,14 +9,15 @@ The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values. -| Variable | Description | Default | -|----------------------------|------------------------------------------------|-----------------------| -| MF_COAP_ADAPTER_PORT | Service listening port | 5683 | -| MF_NATS_URL | NATS instance URL | nats://localhost:4222 | -| MF_THINGS_URL | Things service URL | localhost:8181 | -| MF_COAP_ADAPTER_LOG_LEVEL | Service log level | error | -| MF_COAP_ADAPTER_CLIENT_TLS | Flag that indicates if TLS should be turned on | false | -| MF_COAP_ADAPTER_CA_CERTS | Path to trusted CAs in PEM format | | +| Variable | Description | Default | +|-----------------------------|--------------------------------------------------------|-----------------------| +| MF_COAP_ADAPTER_PORT | Service listening port | 5683 | +| MF_NATS_URL | NATS instance URL | nats://localhost:4222 | +| MF_THINGS_URL | Things service URL | localhost:8181 | +| MF_COAP_ADAPTER_LOG_LEVEL | Service log level | error | +| MF_COAP_ADAPTER_CLIENT_TLS | Flag that indicates if TLS should be turned on | false | +| MF_COAP_ADAPTER_CA_CERTS | Path to trusted CAs in PEM format | | +| MF_COAP_ADAPTER_PING_PERIOD | Hours between 1 and 24 to ping client with ACK message | 12 | ## Deployment @@ -38,6 +39,7 @@ services: MF_COAP_ADAPTER_LOG_LEVEL: [Service log level] MF_COAP_ADAPTER_CLIENT_TLS: [Flag that indicates if TLS should be turned on] MF_COAP_ADAPTER_CA_CERTS: [Path to trusted CAs in PEM format] + MF_COAP_ADAPTER_PING_PERIOD: [Hours between 1 and 24 to ping client with ACK message] ``` Running this service outside of container requires working instance of the NATS service. @@ -56,7 +58,7 @@ make coap make install # set the environment variables and run the service -MF_THINGS_URL=[Things service URL] MF_NATS_URL=[NATS instance URL] MF_COAP_ADAPTER_PORT=[Service HTTP port] MF_COAP_ADAPTER_LOG_LEVEL=[Service log level] MF_COAP_ADAPTER_CLIENT_TLS=[Flag that indicates if TLS should be turned on] MF_COAP_ADAPTER_CA_CERTS=[Path to trusted CAs in PEM format] $GOBIN/mainflux-coap +MF_THINGS_URL=[Things service URL] MF_NATS_URL=[NATS instance URL] MF_COAP_ADAPTER_PORT=[Service HTTP port] MF_COAP_ADAPTER_LOG_LEVEL=[Service log level] MF_COAP_ADAPTER_CLIENT_TLS=[Flag that indicates if TLS should be turned on] MF_COAP_ADAPTER_CA_CERTS=[Path to trusted CAs in PEM format] MF_COAP_ADAPTER_PING_PERIOD: [Hours between 1 and 24 to ping client with ACK message] $GOBIN/mainflux-coap ``` ## Usage diff --git a/coap/api/transport.go b/coap/api/transport.go index ab164808..db707711 100644 --- a/coap/api/transport.go +++ b/coap/api/transport.go @@ -38,6 +38,7 @@ var ( errBadOption = errors.New("bad option") auth mainflux.ThingsServiceClient logger log.Logger + pingPeriod time.Duration ) type handler func(conn *net.UDPConn, addr *net.UDPAddr, msg *gocoap.Message) *gocoap.Message @@ -62,10 +63,10 @@ func MakeHTTPHandler() http.Handler { } // MakeCOAPHandler creates handler for CoAP messages. -func MakeCOAPHandler(svc coap.Service, tc mainflux.ThingsServiceClient, l log.Logger, responses chan<- string) gocoap.Handler { +func MakeCOAPHandler(svc coap.Service, tc mainflux.ThingsServiceClient, l log.Logger, responses chan<- string, pp time.Duration) gocoap.Handler { auth = tc logger = l - + pingPeriod = pp r := mux.NewRouter() r.Handle("/channels/{id}/messages", gocoap.FuncHandler(receive(svc))).Methods(gocoap.POST) r.Handle("/channels/{id}/messages", gocoap.FuncHandler(observe(svc, responses))) @@ -262,8 +263,8 @@ func ping(svc coap.Service, obsID string, conn *net.UDPConn, addr *net.UDPAddr, pingMsg.Type = gocoap.Confirmable pingMsg.RemoveOption(gocoap.URIQuery) // According to RFC (https://tools.ietf.org/html/rfc7641#page-18), CON message must be sent at least every - // 24 hours. Since 24 hours is too long for our purposes, we use 12. - t := time.NewTicker(12 * time.Hour) + // 24 hours. Deafault value of pingPeriod is 12. + t := time.NewTicker(pingPeriod * time.Hour) defer t.Stop() for { select {