1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-28 13:48:49 +08:00

Update mqtt adapter imports (#1081)

* Fixed mqtt adapter imports

Signed-off-by: Nikola Marcetic <n.marcetic86@gmail.com>

* PR remakrs resolved

Signed-off-by: Nikola Marcetic <n.marcetic86@gmail.com>
This commit is contained in:
Nikola Marčetić 2020-03-24 11:07:41 +01:00 committed by GitHub
parent 19503742a6
commit 6ffa916ed2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 362 additions and 151 deletions

2
.env
View File

@ -81,7 +81,7 @@ MF_MQTT_ADAPTER_LOG_LEVEL=debug
MF_MQTT_ADAPTER_PORT=1883 MF_MQTT_ADAPTER_PORT=1883
MF_MQTT_BROKER_PORT=1883 MF_MQTT_BROKER_PORT=1883
MF_MQTT_ADAPTER_WS_PORT=8080 MF_MQTT_ADAPTER_WS_PORT=8080
MF_MQTT_BROKER_WS_PORT=8881 MF_MQTT_BROKER_WS_PORT=8080
MF_MQTT_ADAPTER_ES_DB=0 MF_MQTT_ADAPTER_ES_DB=0
MF_MQTT_ADAPTER_ES_PASS= MF_MQTT_ADAPTER_ES_PASS=

View File

@ -5,6 +5,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http"
"os" "os"
"os/signal" "os/signal"
"strconv" "strconv"
@ -19,6 +20,7 @@ import (
mr "github.com/mainflux/mainflux/mqtt/redis" mr "github.com/mainflux/mainflux/mqtt/redis"
thingsapi "github.com/mainflux/mainflux/things/api/auth/grpc" thingsapi "github.com/mainflux/mainflux/things/api/auth/grpc"
mp "github.com/mainflux/mproxy/pkg/mqtt" mp "github.com/mainflux/mproxy/pkg/mqtt"
ws "github.com/mainflux/mproxy/pkg/websocket"
broker "github.com/nats-io/nats.go" broker "github.com/nats-io/nats.go"
opentracing "github.com/opentracing/opentracing-go" opentracing "github.com/opentracing/opentracing-go"
jconfig "github.com/uber/jaeger-client-go/config" jconfig "github.com/uber/jaeger-client-go/config"
@ -27,30 +29,51 @@ import (
) )
const ( const (
// MQTT
defMQTTHost = "0.0.0.0" defMQTTHost = "0.0.0.0"
defMQTTPort = "1883" defMQTTPort = "1883"
defMQTTTargetHost = "0.0.0.0" defMQTTTargetHost = "0.0.0.0"
defMQTTTargetPort = "1884" defMQTTTargetPort = "1883"
envMQTTHost = "MF_MQTT_ADAPTER_MQTT_HOST" envMQTTHost = "MF_MQTT_ADAPTER_MQTT_HOST"
envMQTTPort = "MF_MQTT_ADAPTER_MQTT_PORT" envMQTTPort = "MF_MQTT_ADAPTER_MQTT_PORT"
envMQTTTargetHost = "MF_MQTT_ADAPTER_MQTT_TARGET_HOST" envMQTTTargetHost = "MF_MQTT_ADAPTER_MQTT_TARGET_HOST"
envMQTTTargetPort = "MF_MQTT_ADAPTER_MQTT_TARGET_PORT" envMQTTTargetPort = "MF_MQTT_ADAPTER_MQTT_TARGET_PORT"
// HTTP
defHTTPHost = "0.0.0.0"
defHTTPPort = "8080"
defHTTPScheme = "ws"
defHTTPTargetHost = "localhost"
defHTTPTargetPort = "8080"
defHTTPTargetPath = "/mqtt"
envHTTPHost = "MF_MQTT_ADAPTER_WS_HOST"
envHTTPPort = "MF_MQTT_ADAPTER_WS_PORT"
envHTTPScheme = "MF_MQTT_ADAPTER_WS_SCHEMA"
envHTTPTargetHost = "MF_MQTT_ADAPTER_WS_TARGET_HOST"
envHTTPTargetPort = "MF_MQTT_ADAPTER_WS_TARGET_PORT"
envHTTPTargetPath = "MF_MQTT_ADAPTER_WS_TARGET_PATH"
// Logging
defLogLevel = "error" defLogLevel = "error"
envLogLevel = "MF_MQTT_ADAPTER_LOG_LEVEL" envLogLevel = "MF_MQTT_ADAPTER_LOG_LEVEL"
// Things
defThingsURL = "localhost:8181" defThingsURL = "localhost:8181"
defThingsTimeout = "1" // in seconds defThingsTimeout = "1" // in seconds
envThingsURL = "MF_THINGS_URL" envThingsURL = "MF_THINGS_URL"
envThingsTimeout = "MF_MQTT_ADAPTER_THINGS_TIMEOUT" envThingsTimeout = "MF_MQTT_ADAPTER_THINGS_TIMEOUT"
// Nats
defNatsURL = broker.DefaultURL defNatsURL = broker.DefaultURL
envNatsURL = "MF_NATS_URL" envNatsURL = "MF_NATS_URL"
// Jaeger
defJaegerURL = "" defJaegerURL = ""
envJaegerURL = "MF_JAEGER_URL" envJaegerURL = "MF_JAEGER_URL"
// TLS
defClientTLS = "false" defClientTLS = "false"
defCACerts = "" defCACerts = ""
envClientTLS = "MF_MQTT_ADAPTER_CLIENT_TLS" envClientTLS = "MF_MQTT_ADAPTER_CLIENT_TLS"
envCACerts = "MF_MQTT_ADAPTER_CA_CERTS" envCACerts = "MF_MQTT_ADAPTER_CA_CERTS"
// Instance
envInstance = "MF_MQTT_ADAPTER_INSTANCE" envInstance = "MF_MQTT_ADAPTER_INSTANCE"
defInstance = "" defInstance = ""
// ES
envESURL = "MF_MQTT_ADAPTER_ES_URL" envESURL = "MF_MQTT_ADAPTER_ES_URL"
envESPass = "MF_MQTT_ADAPTER_ES_PASS" envESPass = "MF_MQTT_ADAPTER_ES_PASS"
envESDB = "MF_MQTT_ADAPTER_ES_DB" envESDB = "MF_MQTT_ADAPTER_ES_DB"
@ -64,6 +87,12 @@ type config struct {
mqttPort string mqttPort string
mqttTargetHost string mqttTargetHost string
mqttTargetPort string mqttTargetPort string
httpHost string
httpPort string
httpScheme string
httpTargetHost string
httpTargetPort string
httpTargetPath string
jaegerURL string jaegerURL string
logLevel string logLevel string
thingsURL string thingsURL string
@ -118,6 +147,9 @@ func main() {
logger.Info(fmt.Sprintf("Starting MQTT proxy on port %s", cfg.mqttPort)) logger.Info(fmt.Sprintf("Starting MQTT proxy on port %s", cfg.mqttPort))
go proxyMQTT(cfg, logger, evt, errs) go proxyMQTT(cfg, logger, evt, errs)
logger.Info(fmt.Sprintf("Starting MQTT over WS proxy on port %s", cfg.httpPort))
go proxyWS(cfg, logger, evt, errs)
go func() { go func() {
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT) signal.Notify(c, syscall.SIGINT)
@ -144,6 +176,12 @@ func loadConfig() config {
mqttPort: mainflux.Env(envMQTTPort, defMQTTPort), mqttPort: mainflux.Env(envMQTTPort, defMQTTPort),
mqttTargetHost: mainflux.Env(envMQTTTargetHost, defMQTTTargetHost), mqttTargetHost: mainflux.Env(envMQTTTargetHost, defMQTTTargetHost),
mqttTargetPort: mainflux.Env(envMQTTTargetPort, defMQTTTargetPort), mqttTargetPort: mainflux.Env(envMQTTTargetPort, defMQTTTargetPort),
httpHost: mainflux.Env(envHTTPHost, defHTTPHost),
httpPort: mainflux.Env(envHTTPPort, defHTTPPort),
httpScheme: mainflux.Env(envHTTPScheme, defHTTPScheme),
httpTargetHost: mainflux.Env(envHTTPTargetHost, defHTTPTargetHost),
httpTargetPort: mainflux.Env(envHTTPTargetPort, defHTTPTargetPort),
httpTargetPath: mainflux.Env(envHTTPTargetPath, defHTTPTargetPath),
jaegerURL: mainflux.Env(envJaegerURL, defJaegerURL), jaegerURL: mainflux.Env(envJaegerURL, defJaegerURL),
thingsTimeout: time.Duration(timeout) * time.Second, thingsTimeout: time.Duration(timeout) * time.Second,
thingsURL: mainflux.Env(envThingsURL, defThingsURL), thingsURL: mainflux.Env(envThingsURL, defThingsURL),
@ -221,7 +259,17 @@ func connectToRedis(redisURL, redisPass, redisDB string, logger logger.Logger) *
} }
func proxyMQTT(cfg config, logger logger.Logger, evt *mqtt.Event, errs chan error) { func proxyMQTT(cfg config, logger logger.Logger, evt *mqtt.Event, errs chan error) {
mp := mp.New(cfg.mqttHost, cfg.mqttPort, cfg.mqttTargetHost, cfg.mqttTargetPort, evt, logger) address := fmt.Sprintf("%s:%s", cfg.mqttHost, cfg.mqttPort)
target := fmt.Sprintf("%s:%s", cfg.mqttTargetHost, cfg.mqttTargetPort)
mp := mp.New(address, target, evt, logger)
errs <- mp.Proxy() errs <- mp.Proxy()
} }
func proxyWS(cfg config, logger logger.Logger, evt *mqtt.Event, errs chan error) {
target := fmt.Sprintf("%s:%s", cfg.httpTargetHost, cfg.httpTargetPort)
wp := ws.New(target, cfg.httpTargetPath, cfg.httpScheme, evt, logger)
http.Handle("/mqtt", wp.Handler())
p := fmt.Sprintf(":%s", cfg.httpPort)
errs <- http.ListenAndServe(p, nil)
}

View File

@ -208,7 +208,7 @@ services:
restart: on-failure restart: on-failure
environment: environment:
DOCKER_VERNEMQ_ALLOW_ANONYMOUS: "on" DOCKER_VERNEMQ_ALLOW_ANONYMOUS: "on"
DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL: info DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL: debug
ports: ports:
- 18831:${MF_MQTT_BROKER_PORT} - 18831:${MF_MQTT_BROKER_PORT}
- 8881:${MF_MQTT_BROKER_WS_PORT} - 8881:${MF_MQTT_BROKER_WS_PORT}
@ -236,6 +236,8 @@ services:
MF_JAEGER_URL: ${MF_JAEGER_URL} MF_JAEGER_URL: ${MF_JAEGER_URL}
MF_MQTT_ADAPTER_MQTT_TARGET_HOST: vernemq MF_MQTT_ADAPTER_MQTT_TARGET_HOST: vernemq
MF_MQTT_ADAPTER_MQTT_TARGET_PORT: ${MF_MQTT_BROKER_PORT} MF_MQTT_ADAPTER_MQTT_TARGET_PORT: ${MF_MQTT_BROKER_PORT}
MF_MQTT_ADAPTER_WS_TARGET_HOST: vernemq
MF_MQTT_ADAPTER_WS_TARGET_PORT: ${MF_MQTT_BROKER_WS_PORT}
ports: ports:
- 18832:${MF_MQTT_ADAPTER_PORT} - 18832:${MF_MQTT_ADAPTER_PORT}
- 8882:${MF_MQTT_ADAPTER_WS_PORT} - 8882:${MF_MQTT_ADAPTER_WS_PORT}

13
go.mod
View File

@ -4,8 +4,6 @@ go 1.11
require ( require (
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/bitly/go-hostpool v0.1.0 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/docker/docker v1.13.1 github.com/docker/docker v1.13.1
github.com/dustin/go-coap v0.0.0-20170214053734-ddcc80675fa4 github.com/dustin/go-coap v0.0.0-20170214053734-ddcc80675fa4
@ -14,21 +12,18 @@ require (
github.com/go-kit/kit v0.9.0 github.com/go-kit/kit v0.9.0
github.com/go-redis/redis v6.15.0+incompatible github.com/go-redis/redis v6.15.0+incompatible
github.com/go-zoo/bone v1.3.0 github.com/go-zoo/bone v1.3.0
github.com/gobuffalo/packr v1.30.1 // indirect
github.com/gocql/gocql v0.0.0-20181106112037-68ae1e384be4 github.com/gocql/gocql v0.0.0-20181106112037-68ae1e384be4
github.com/gofrs/uuid v3.2.0+incompatible github.com/gofrs/uuid v3.2.0+incompatible
github.com/gogo/protobuf v1.3.1 github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.3 github.com/golang/protobuf v1.3.3
github.com/gopcua/opcua v0.1.6 github.com/gopcua/opcua v0.1.6
github.com/gorilla/websocket v1.4.1 github.com/gorilla/websocket v1.4.1
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
github.com/hokaccha/go-prettyjson v0.0.0-20180920040306-f579f869bbfe github.com/hokaccha/go-prettyjson v0.0.0-20180920040306-f579f869bbfe
github.com/influxdata/influxdb v1.6.4 github.com/influxdata/influxdb v1.6.4
github.com/jmoiron/sqlx v1.2.1-0.20190319043955-cdf62fdf55f6 github.com/jmoiron/sqlx v1.2.1-0.20190319043955-cdf62fdf55f6
github.com/lib/pq v1.0.0 github.com/lib/pq v1.0.0
github.com/mainflux/mproxy v0.1.3 github.com/mainflux/mproxy v0.1.5
github.com/mainflux/senml v1.0.1 github.com/mainflux/senml v1.0.1
github.com/nats-io/nats-server/v2 v2.1.4 // indirect
github.com/nats-io/nats.go v1.9.1 github.com/nats-io/nats.go v1.9.1
github.com/opentracing/opentracing-go v1.1.0 github.com/opentracing/opentracing-go v1.1.0
github.com/prometheus/client_golang v0.9.3 github.com/prometheus/client_golang v0.9.3
@ -37,17 +32,11 @@ require (
github.com/spf13/cobra v0.0.5 github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.5.0 github.com/spf13/viper v1.5.0
github.com/stretchr/testify v1.5.1 github.com/stretchr/testify v1.5.1
github.com/tidwall/pretty v1.0.0 // indirect
github.com/uber/jaeger-client-go v2.22.1+incompatible github.com/uber/jaeger-client-go v2.22.1+incompatible
github.com/ziutek/mymysql v1.5.4 // indirect
go.mongodb.org/mongo-driver v1.1.3 go.mongodb.org/mongo-driver v1.1.3
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect
golang.org/x/text v0.3.2 // indirect
gonum.org/v1/gonum v0.0.0-20190808205415-ced62fe5104b gonum.org/v1/gonum v0.0.0-20190808205415-ced62fe5104b
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 // indirect
google.golang.org/grpc v1.27.1 google.golang.org/grpc v1.27.1
gopkg.in/ory/dockertest.v3 v3.3.5 gopkg.in/ory/dockertest.v3 v3.3.5
gotest.tools v2.2.0+incompatible // indirect
) )

7
go.sum
View File

@ -113,6 +113,7 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopcua/opcua v0.1.6 h1:B9SVRKQGzcWcwP2QPYN93Uku32+3wL+v5cgzBxE6V5I= github.com/gopcua/opcua v0.1.6 h1:B9SVRKQGzcWcwP2QPYN93Uku32+3wL+v5cgzBxE6V5I=
github.com/gopcua/opcua v0.1.6/go.mod h1:INwnDoRxmNWAt7+tzqxuGqQkSF2c1C69VAL0c2q6AcY= github.com/gopcua/opcua v0.1.6/go.mod h1:INwnDoRxmNWAt7+tzqxuGqQkSF2c1C69VAL0c2q6AcY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@ -163,8 +164,13 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mainflux/mainflux v0.0.0-20191223163044-f42f2095bab4/go.mod h1:K3ghSIpAqwv5F/t30LO57+11S7tE97ur2Z6wWEHa2CA= github.com/mainflux/mainflux v0.0.0-20191223163044-f42f2095bab4/go.mod h1:K3ghSIpAqwv5F/t30LO57+11S7tE97ur2Z6wWEHa2CA=
github.com/mainflux/mainflux v0.0.0-20200314190902-c91fe0d45353/go.mod h1:yijZGLNkcDOPJfPhRMwuu5ZFcNHqDHzWurN4q1rOT/Q=
github.com/mainflux/mproxy v0.1.3 h1:/JNnxgo/03wSpbwQH2+WE1AzgMWaSKogTVXblh18x5s= github.com/mainflux/mproxy v0.1.3 h1:/JNnxgo/03wSpbwQH2+WE1AzgMWaSKogTVXblh18x5s=
github.com/mainflux/mproxy v0.1.3/go.mod h1:/BdaBfgye1GNCD+eat4ipFamy9IEVRH5nhZS0yEShVg= github.com/mainflux/mproxy v0.1.3/go.mod h1:/BdaBfgye1GNCD+eat4ipFamy9IEVRH5nhZS0yEShVg=
github.com/mainflux/mproxy v0.1.4 h1:g7LhJgA+BXlgaZeyLj505aD5DCsrix79TEiLWuHJZd4=
github.com/mainflux/mproxy v0.1.4/go.mod h1:MBLtv/RvhT8QsmXz4g3GxkRaP8PqlVqBWeqvw9QmO8k=
github.com/mainflux/mproxy v0.1.5 h1:a0zKiUyuTDld2TwCuhrOFtUvotcvSfwJMuh/JcrqC6I=
github.com/mainflux/mproxy v0.1.5/go.mod h1:MBLtv/RvhT8QsmXz4g3GxkRaP8PqlVqBWeqvw9QmO8k=
github.com/mainflux/senml v1.0.0 h1:oLS5aBhvdHjgQ8kfq3jX7yD+DaquhvpyvIWNsPil3X0= github.com/mainflux/senml v1.0.0 h1:oLS5aBhvdHjgQ8kfq3jX7yD+DaquhvpyvIWNsPil3X0=
github.com/mainflux/senml v1.0.0/go.mod h1:g9i8pj4WMs29KkUpXivbe/PP0qJd1kt3b1CF77S8A3s= github.com/mainflux/senml v1.0.0/go.mod h1:g9i8pj4WMs29KkUpXivbe/PP0qJd1kt3b1CF77S8A3s=
github.com/mainflux/senml v1.0.1 h1:qWKIGeUe7YEygM3xZcJ9Lbq+DHuT8V23dz1hgAYkYEY= github.com/mainflux/senml v1.0.1 h1:qWKIGeUe7YEygM3xZcJ9Lbq+DHuT8V23dz1hgAYkYEY=
@ -390,6 +396,7 @@ google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO50
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 h1:1+0Z5cgv1eDXJD9z2tdQF9PSSQnJXwism490hJydMRI= google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 h1:1+0Z5cgv1eDXJD9z2tdQF9PSSQnJXwism490hJydMRI=
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=

View File

@ -14,11 +14,11 @@ import (
"github.com/mainflux/mainflux" "github.com/mainflux/mainflux"
"github.com/mainflux/mainflux/logger" "github.com/mainflux/mainflux/logger"
"github.com/mainflux/mainflux/mqtt/redis" "github.com/mainflux/mainflux/mqtt/redis"
"github.com/mainflux/mproxy/pkg/mqtt" "github.com/mainflux/mproxy/pkg/session"
opentracing "github.com/opentracing/opentracing-go" opentracing "github.com/opentracing/opentracing-go"
) )
var _ mqtt.Event = (*Event)(nil) var _ session.Event = (*Event)(nil)
var ( var (
channelRegExp = regexp.MustCompile(`^\/?channels\/([\w\-]+)\/messages(\/[^?]*)?(\?.*)?$`) channelRegExp = regexp.MustCompile(`^\/?channels\/([\w\-]+)\/messages(\/[^?]*)?(\?.*)?$`)
@ -56,11 +56,11 @@ func New(tc mainflux.ThingsServiceClient, pubs []mainflux.MessagePublisher, es r
// AuthConnect is called on device connection, // AuthConnect is called on device connection,
// prior forwarding to the MQTT broker // prior forwarding to the MQTT broker
func (e *Event) AuthConnect(c *mqtt.Client) error { func (e *Event) AuthConnect(c *session.Client) error {
if c == nil { if c == nil {
return errInvalidConnect return errInvalidConnect
} }
e.logger.Info(fmt.Sprintf("AuthConenct - client ID: %s, username: %s", c.ID, c.Username)) e.logger.Info(fmt.Sprintf("AuthConnect - client ID: %s, username: %s", c.ID, c.Username))
t := &mainflux.Token{ t := &mainflux.Token{
Value: string(c.Password), Value: string(c.Password),
@ -84,7 +84,7 @@ func (e *Event) AuthConnect(c *mqtt.Client) error {
// AuthPublish is called on device publish, // AuthPublish is called on device publish,
// prior forwarding to the MQTT broker // prior forwarding to the MQTT broker
func (e *Event) AuthPublish(c *mqtt.Client, topic *string, payload *[]byte) error { func (e *Event) AuthPublish(c *session.Client, topic *string, payload *[]byte) error {
if c == nil { if c == nil {
return errNilClient return errNilClient
} }
@ -97,7 +97,7 @@ func (e *Event) AuthPublish(c *mqtt.Client, topic *string, payload *[]byte) erro
// AuthSubscribe is called on device publish, // AuthSubscribe is called on device publish,
// prior forwarding to the MQTT broker // prior forwarding to the MQTT broker
func (e *Event) AuthSubscribe(c *mqtt.Client, topics *[]string) error { func (e *Event) AuthSubscribe(c *session.Client, topics *[]string) error {
if c == nil { if c == nil {
return errNilClient return errNilClient
} }
@ -117,7 +117,7 @@ func (e *Event) AuthSubscribe(c *mqtt.Client, topics *[]string) error {
} }
// Connect - after client sucesfully connected // Connect - after client sucesfully connected
func (e *Event) Connect(c *mqtt.Client) { func (e *Event) Connect(c *session.Client) {
if c == nil { if c == nil {
e.logger.Error("Nil client connect") e.logger.Error("Nil client connect")
return return
@ -126,7 +126,7 @@ func (e *Event) Connect(c *mqtt.Client) {
} }
// Publish - after client sucesfully published // Publish - after client sucesfully published
func (e *Event) Publish(c *mqtt.Client, topic *string, payload *[]byte) { func (e *Event) Publish(c *session.Client, topic *string, payload *[]byte) {
if c == nil { if c == nil {
e.logger.Error("Nil client publish") e.logger.Error("Nil client publish")
return return
@ -175,7 +175,7 @@ func (e *Event) Publish(c *mqtt.Client, topic *string, payload *[]byte) {
} }
// Subscribe - after client sucesfully subscribed // Subscribe - after client sucesfully subscribed
func (e *Event) Subscribe(c *mqtt.Client, topics *[]string) { func (e *Event) Subscribe(c *session.Client, topics *[]string) {
if c == nil { if c == nil {
e.logger.Error("Nil client subscribe") e.logger.Error("Nil client subscribe")
return return
@ -184,7 +184,7 @@ func (e *Event) Subscribe(c *mqtt.Client, topics *[]string) {
} }
// Unsubscribe - after client unsubscribed // Unsubscribe - after client unsubscribed
func (e *Event) Unsubscribe(c *mqtt.Client, topics *[]string) { func (e *Event) Unsubscribe(c *session.Client, topics *[]string) {
if c == nil { if c == nil {
e.logger.Error("Nil client unsubscribe") e.logger.Error("Nil client unsubscribe")
return return
@ -193,7 +193,7 @@ func (e *Event) Unsubscribe(c *mqtt.Client, topics *[]string) {
} }
// Disconnect - connection with broker or client lost // Disconnect - connection with broker or client lost
func (e *Event) Disconnect(c *mqtt.Client) { func (e *Event) Disconnect(c *session.Client) {
if c == nil { if c == nil {
e.logger.Error("Nil client disconnect") e.logger.Error("Nil client disconnect")
return return

71
vendor/github.com/mainflux/mproxy/pkg/mqtt/mqtt.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
package mqtt
import (
"io"
"net"
"github.com/mainflux/mainflux/logger"
"github.com/mainflux/mproxy/pkg/session"
)
// Proxy is main MQTT proxy struct
type Proxy struct {
address string
target string
event session.Event
logger logger.Logger
}
func New(address, target string, event session.Event, logger logger.Logger) *Proxy {
return &Proxy{
address: address,
target: target,
event: event,
logger: logger,
}
}
func (p Proxy) accept(l net.Listener) {
for {
conn, err := l.Accept()
if err != nil {
p.logger.Warn("Accept error " + err.Error())
continue
}
p.logger.Info("Accepted new client")
go p.handleConnection(conn)
}
}
func (p Proxy) handleConnection(inbound net.Conn) {
defer inbound.Close()
outbound, err := net.Dial("tcp", p.target)
if err != nil {
p.logger.Error("Cannot connect to remote broker " + p.target)
return
}
defer outbound.Close()
c := session.New(inbound, outbound, p.event, p.logger)
if err := c.Stream(); err != io.EOF {
p.logger.Warn("Broken connection for client: " + c.Client.ID + " with error: " + err.Error())
}
}
// Proxy of the server, this will block.
func (p Proxy) Proxy() error {
l, err := net.Listen("tcp", p.address)
if err != nil {
return err
}
defer l.Close()
// Acceptor loop
p.accept(l)
p.logger.Info("Server Exiting...")
return nil
}

View File

@ -1,75 +0,0 @@
package mqtt
import (
"fmt"
"io"
"net"
"github.com/mainflux/mainflux/logger"
)
// Proxy is main MQTT proxy struct
type Proxy struct {
host string
port string
target string
event Event
logger logger.Logger
}
// New will setup a new Proxy struct after parsing the options
func New(host, port, targetHost, targetPort string, event Event, logger logger.Logger) *Proxy {
return &Proxy{
host: host,
port: port,
target: fmt.Sprintf("%s:%s", targetHost, targetPort),
event: event,
logger: logger,
}
}
func (p *Proxy) accept(l net.Listener) {
for {
conn, err := l.Accept()
if err != nil {
p.logger.Warn("Accept error " + err.Error())
continue
}
p.logger.Info("Accepted new client")
go p.handleConnection(conn)
}
}
func (p *Proxy) handleConnection(inbound net.Conn) {
defer inbound.Close()
outbound, err := net.Dial("tcp", p.target)
if err != nil {
p.logger.Error("Cannot connect to remote broker " + p.target)
return
}
defer outbound.Close()
s := newSession(inbound, outbound, p.event, p.logger)
if err := s.stream(); err != io.EOF {
p.logger.Warn("Exited session for client " + s.client.ID + " with error: " + err.Error())
}
s.logger.Info("Session for client " + s.client.ID + " closed: " + s.outbound.LocalAddr().String())
}
// Proxy of the server, this will block.
func (p *Proxy) Proxy() error {
addr := fmt.Sprintf("%s:%s", p.host, p.port)
l, err := net.Listen("tcp", addr)
if err != nil {
return err
}
defer l.Close()
// Acceptor loop
p.accept(l)
p.logger.Info("Server Exiting...")
return nil
}

View File

@ -1,4 +1,4 @@
package mqtt package session
// Client stores MQTT client data. // Client stores MQTT client data.
type Client struct { type Client struct {

View File

@ -1,4 +1,4 @@
package mqtt package session
// Event is an interface for mProxy hooks // Event is an interface for mProxy hooks
type Event interface { type Event interface {

View File

@ -1,4 +1,4 @@
package mqtt package session
import ( import (
"net" "net"
@ -14,16 +14,16 @@ const (
type direction int type direction int
type session struct { type Session struct {
logger logger.Logger logger logger.Logger
inbound net.Conn inbound net.Conn
outbound net.Conn outbound net.Conn
event Event event Event
client Client Client Client
} }
func newSession(inbound, outbound net.Conn, event Event, logger logger.Logger) *session { func New(inbound, outbound net.Conn, event Event, logger logger.Logger) *Session {
return &session{ return &Session{
logger: logger, logger: logger,
inbound: inbound, inbound: inbound,
outbound: outbound, outbound: outbound,
@ -31,20 +31,20 @@ func newSession(inbound, outbound net.Conn, event Event, logger logger.Logger) *
} }
} }
func (s *session) stream() error { func (s Session) Stream() error {
// In parallel read from client, send to broker // In parallel read from client, send to broker
// and read from broker, send to client // and read from broker, send to client
errs := make(chan error, 2) errs := make(chan error, 2)
go s.streamUnidir(up, s.inbound, s.outbound, errs) go s.stream(up, s.inbound, s.outbound, errs)
go s.streamUnidir(down, s.outbound, s.inbound, errs) go s.stream(down, s.outbound, s.inbound, errs)
err := <-errs err := <-errs
s.event.Disconnect(&s.client) s.event.Disconnect(&s.Client)
return err return err
} }
func (s *session) streamUnidir(dir direction, r, w net.Conn, errs chan error) { func (s Session) stream(dir direction, r, w net.Conn, errs chan error) {
for { for {
// Read from one connection // Read from one connection
pkt, err := packets.ReadPacket(r) pkt, err := packets.ReadPacket(r)
@ -72,42 +72,42 @@ func (s *session) streamUnidir(dir direction, r, w net.Conn, errs chan error) {
} }
} }
func (s *session) authorize(pkt packets.ControlPacket) error { func (s *Session) authorize(pkt packets.ControlPacket) error {
switch p := pkt.(type) { switch p := pkt.(type) {
case *packets.ConnectPacket: case *packets.ConnectPacket:
s.client = Client{ s.Client = Client{
ID: p.ClientIdentifier, ID: p.ClientIdentifier,
Username: p.Username, Username: p.Username,
Password: p.Password, Password: p.Password,
} }
if err := s.event.AuthConnect(&s.client); err != nil { if err := s.event.AuthConnect(&s.Client); err != nil {
return err return err
} }
// Copy back to the packet in case values are changed by Event handler. // Copy back to the packet in case values are changed by Event handler.
// This is specific to CONN, as only that package type has credentials. // This is specific to CONN, as only that package type has credentials.
p.ClientIdentifier = s.client.ID p.ClientIdentifier = s.Client.ID
p.Username = s.client.Username p.Username = s.Client.Username
p.Password = s.client.Password p.Password = s.Client.Password
return nil return nil
case *packets.PublishPacket: case *packets.PublishPacket:
return s.event.AuthPublish(&s.client, &p.TopicName, &p.Payload) return s.event.AuthPublish(&s.Client, &p.TopicName, &p.Payload)
case *packets.SubscribePacket: case *packets.SubscribePacket:
return s.event.AuthSubscribe(&s.client, &p.Topics) return s.event.AuthSubscribe(&s.Client, &p.Topics)
default: default:
return nil return nil
} }
} }
func (s *session) notify(pkt packets.ControlPacket) { func (s Session) notify(pkt packets.ControlPacket) {
switch p := pkt.(type) { switch p := pkt.(type) {
case *packets.ConnectPacket: case *packets.ConnectPacket:
s.event.Connect(&s.client) s.event.Connect(&s.Client)
case *packets.PublishPacket: case *packets.PublishPacket:
s.event.Publish(&s.client, &p.TopicName, &p.Payload) s.event.Publish(&s.Client, &p.TopicName, &p.Payload)
case *packets.SubscribePacket: case *packets.SubscribePacket:
s.event.Subscribe(&s.client, &p.Topics) s.event.Subscribe(&s.Client, &p.Topics)
case *packets.UnsubscribePacket: case *packets.UnsubscribePacket:
s.event.Unsubscribe(&s.client, &p.Topics) s.event.Unsubscribe(&s.Client, &p.Topics)
default: default:
return return
} }

View File

@ -0,0 +1,78 @@
package websocket
import (
"io"
"net"
"sync"
"time"
"github.com/gorilla/websocket"
)
// wsWrapper is a websocket wrapper so it satisfies the net.Conn interface.
type wsWrapper struct {
*websocket.Conn
r io.Reader
rio sync.Mutex
wio sync.Mutex
}
func newConn(ws *websocket.Conn) net.Conn {
wrapper := &wsWrapper{
Conn: ws,
}
return wrapper
}
// SetDeadline sets both the read and write deadlines
func (c *wsWrapper) SetDeadline(t time.Time) error {
if err := c.SetReadDeadline(t); err != nil {
return err
}
err := c.SetWriteDeadline(t)
return err
}
// Write writes data to the websocket
func (c *wsWrapper) Write(p []byte) (int, error) {
c.wio.Lock()
defer c.wio.Unlock()
err := c.WriteMessage(websocket.BinaryMessage, p)
if err != nil {
return 0, err
}
return len(p), nil
}
// Read reads the current websocket frame
func (c *wsWrapper) Read(p []byte) (int, error) {
c.rio.Lock()
defer c.rio.Unlock()
for {
if c.r == nil {
// Advance to next message.
var err error
_, c.r, err = c.NextReader()
if err != nil {
return 0, err
}
}
n, err := c.r.Read(p)
if err == io.EOF {
// At end of message.
c.r = nil
if n > 0 {
return n, nil
}
// No data read, continue to next message.
continue
}
return n, err
}
}
func (c *wsWrapper) Close() error {
return c.Conn.Close()
}

View File

@ -0,0 +1,89 @@
package websocket
import (
"net/http"
"net/url"
"time"
"github.com/gorilla/websocket"
"github.com/mainflux/mainflux/logger"
"github.com/mainflux/mproxy/pkg/session"
)
// New - creates new HTTP proxy
type Proxy struct {
target string
path string
scheme string
event session.Event
logger logger.Logger
}
func New(target, path, scheme string, event session.Event, logger logger.Logger) *Proxy {
return &Proxy{
target: target,
path: path,
scheme: scheme,
event: event,
logger: logger,
}
}
var upgrader = websocket.Upgrader{
// Timeout for WS upgrade request handshake
HandshakeTimeout: 10 * time.Second,
// Paho JS client expecting header Sec-WebSocket-Protocol:mqtt in Upgrade response during handshake.
Subprotocols: []string{"mqtt"},
// Allow CORS
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// Handle - proxies HTTP traffic
func (p Proxy) Handler() http.Handler {
return p.handle()
}
func (p Proxy) handle() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cconn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
p.logger.Error("Error upgrading connection " + err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
go p.pass(cconn)
})
}
func (p Proxy) pass(in *websocket.Conn) {
defer in.Close()
url := url.URL{
Scheme: p.scheme,
Host: p.target,
Path: p.path,
}
srv, _, err := websocket.DefaultDialer.Dial(url.String(), nil)
if err != nil {
p.logger.Error("Unable to connect to broker, reason: " + err.Error())
return
}
errc := make(chan error, 1)
c := newConn(in)
s := newConn(srv)
defer s.Close()
defer c.Close()
session := session.New(c, s, p.event, p.logger)
err = session.Stream()
errc <- err
p.logger.Warn("Broken connection for client: " + session.Client.ID + " with error: " + err.Error())
}

4
vendor/modules.txt vendored
View File

@ -122,8 +122,10 @@ github.com/lib/pq
github.com/lib/pq/oid github.com/lib/pq/oid
# github.com/magiconair/properties v1.8.1 # github.com/magiconair/properties v1.8.1
github.com/magiconair/properties github.com/magiconair/properties
# github.com/mainflux/mproxy v0.1.3 # github.com/mainflux/mproxy v0.1.5
github.com/mainflux/mproxy/pkg/mqtt github.com/mainflux/mproxy/pkg/mqtt
github.com/mainflux/mproxy/pkg/session
github.com/mainflux/mproxy/pkg/websocket
# github.com/mainflux/senml v1.0.1 # github.com/mainflux/senml v1.0.1
github.com/mainflux/senml github.com/mainflux/senml
# github.com/mattn/go-colorable v0.0.9 # github.com/mattn/go-colorable v0.0.9