mirror of
https://github.com/mainflux/mainflux.git
synced 2025-04-24 13:48:49 +08:00
MF-1525 - Add graceful stop for HTTP and GRPC servers (#1548)
* Add : errgroup to cmd/auth Signed-off-by: Arvindh <arvindh91@gmail.com> * Add : Handle graceful stop for auth service Remove : errgroups from auth service Signed-off-by: Arvindh <arvindh91@gmail.com> * Add : Wait till server shutdown Signed-off-by: Arvindh <arvindh91@gmail.com> * Change : instead of waitgroup changed to errgroups Signed-off-by: Arvindh <arvindh91@gmail.com> * change : KillSignalHandler return type to error Signed-off-by: Arvindh <arvindh91@gmail.com> * Empty Commit Signed-off-by: Arvindh <arvindh91@gmail.com> * Add : Context to http server shutdown Rename : varaible from proto to protocol Signed-off-by: Arvindh <arvindh91@gmail.com> * change : to default log level Signed-off-by: Arvindh <arvindh91@gmail.com> * Add : Sign-off Signed-off-by: Arvindh <arvindh91@gmail.com> * Add: graceful stop of http and grpc server Signed-off-by: Arvindh <arvindh91@gmail.com> * Fix: typos and caps Signed-off-by: Arvindh <arvindh91@gmail.com> * Add: Signed-off Signed-off-by: Arvindh <arvindh91@gmail.com> * Rename: Func KillSignalHandler to SignalHandler Add: SIGABRT Signed-off-by: Arvindh <arvindh91@gmail.com> * Fix: auth service Signed-off-by: Arvindh <arvindh91@gmail.com> * Add: timeout for grpc gracefulstop Fix: typos Signed-off-by: Arvindh <arvindh91@gmail.com> * Add: .vscode folder to git ignore Signed-off-by: Arvindh <arvindh91@gmail.com> * change: variable name to stopWaitTime Signed-off-by: Arvindh <arvindh91@gmail.com> * remove: .vscode folder Signed-off-by: Arvindh <arvindh91@gmail.com> * remove: .vscode from .gitignore Signed-off-by: Arvindh <arvindh91@gmail.com> * Add : logger to handlers Signed-off-by: Arvindh <arvindh91@gmail.com> * Add : New line at end of .gitignore file Signed-off-by: Arvindh <arvindh91@gmail.com> * Fix : variable naming Add : graceful stop for timescale Signed-off-by: Arvindh <arvindh91@gmail.com> * Remove : unsued NATS library from import Signed-off-by: Arvindh <arvindh91@gmail.com> * Move: "https" and "https" to moved to const var Signed-off-by: Arvindh <arvindh91@gmail.com> * Move: "http" and "https" to moved to const var Signed-off-by: Arvindh <arvindh91@gmail.com> * update: branch with master Signed-off-by: Arvindh <arvindh91@gmail.com> Co-authored-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com> Co-authored-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com>
This commit is contained in:
parent
195b78303f
commit
b19ba0db7d
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,4 +5,3 @@
|
||||
# https://digitalfortress.tech/tricks/creating-a-global-gitignore/
|
||||
|
||||
build
|
||||
|
||||
|
108
cmd/auth/main.go
108
cmd/auth/main.go
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -8,8 +9,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -24,16 +23,22 @@ import (
|
||||
"github.com/mainflux/mainflux/auth/postgres"
|
||||
"github.com/mainflux/mainflux/auth/tracing"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/uuid"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
acl "github.com/ory/keto/proto/ory/keto/acl/v1alpha1"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
httpProtocol = "http"
|
||||
httpsProtocol = "https"
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -103,7 +108,8 @@ type tokenConfig struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
log.Fatalf(err.Error())
|
||||
@ -121,19 +127,24 @@ func main() {
|
||||
readerConn, writerConn := initKeto(cfg.ketoReadHost, cfg.ketoReadPort, cfg.ketoWriteHost, cfg.ketoWritePort, logger)
|
||||
|
||||
svc := newService(db, dbTracer, cfg.secret, logger, readerConn, writerConn, cfg.loginDuration)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
go startHTTPServer(tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger, errs)
|
||||
go startGRPCServer(tracer, svc, cfg.grpcPort, cfg.serverCert, cfg.serverKey, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger)
|
||||
})
|
||||
g.Go(func() error {
|
||||
return startGRPCServer(ctx, tracer, svc, cfg.grpcPort, cfg.serverCert, cfg.serverKey, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Authentication service terminated: %s", err))
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Authentication service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Authentication service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -254,40 +265,83 @@ func newService(db *sqlx.DB, tracer opentracing.Tracer, secret string, logger lo
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(tracer opentracing.Tracer, svc auth.Service, port string, certFile string, keyFile string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, tracer opentracing.Tracer, svc auth.Service, port string, certFile string, keyFile string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if certFile != "" || keyFile != "" {
|
||||
server := &http.Server{Addr: p, Handler: httpapi.MakeHandler(svc, tracer, logger)}
|
||||
errCh := make(chan error)
|
||||
protocol := httpProtocol
|
||||
switch {
|
||||
case certFile != "" || keyFile != "":
|
||||
logger.Info(fmt.Sprintf("Authentication service started using https, cert %s key %s, exposed port %s", certFile, keyFile, port))
|
||||
errs <- http.ListenAndServeTLS(p, certFile, keyFile, httpapi.MakeHandler(svc, tracer, logger))
|
||||
return
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(certFile, keyFile)
|
||||
}()
|
||||
protocol = httpsProtocol
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Authentication service started using http, exposed port %s", port))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Authentication service started using http, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, httpapi.MakeHandler(svc, tracer, logger))
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Authentication %s service error occurred during shutdown at %s: %s", protocol, p, err))
|
||||
return fmt.Errorf("Authentication %s service error occurred during shutdown at %s: %w", protocol, p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Authentication %s service shutdown of http at %s", protocol, p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func startGRPCServer(tracer opentracing.Tracer, svc auth.Service, port string, certFile string, keyFile string, logger logger.Logger, errs chan error) {
|
||||
func startGRPCServer(ctx context.Context, tracer opentracing.Tracer, svc auth.Service, port string, certFile string, keyFile string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
|
||||
listener, err := net.Listen("tcp", p)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to listen on port %s: %s", port, err))
|
||||
return fmt.Errorf("failed to listen on port %s: %w", port, err)
|
||||
}
|
||||
|
||||
var server *grpc.Server
|
||||
if certFile != "" || keyFile != "" {
|
||||
switch {
|
||||
case certFile != "" || keyFile != "":
|
||||
creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to load auth certificates: %s", err))
|
||||
os.Exit(1)
|
||||
return fmt.Errorf("failed to load auth certificates: %w", err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Authentication gRPC service started using https on port %s with cert %s key %s", port, certFile, keyFile))
|
||||
server = grpc.NewServer(grpc.Creds(creds))
|
||||
} else {
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Authentication gRPC service started using http on port %s", port))
|
||||
server = grpc.NewServer()
|
||||
}
|
||||
|
||||
mainflux.RegisterAuthServiceServer(server, grpcapi.NewServer(tracer, svc))
|
||||
logger.Info(fmt.Sprintf("Authentication gRPC service started, exposed port %s", port))
|
||||
errs <- server.Serve(listener)
|
||||
go func() {
|
||||
errCh <- server.Serve(listener)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
c := make(chan bool)
|
||||
go func() {
|
||||
defer close(c)
|
||||
server.GracefulStop()
|
||||
}()
|
||||
select {
|
||||
case <-c:
|
||||
case <-time.After(stopWaitTime):
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Authentication gRPC service shutdown at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
@ -22,6 +20,7 @@ import (
|
||||
redisprod "github.com/mainflux/mainflux/bootstrap/redis/producer"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
r "github.com/go-redis/redis/v8"
|
||||
@ -31,6 +30,7 @@ import (
|
||||
api "github.com/mainflux/mainflux/bootstrap/api"
|
||||
"github.com/mainflux/mainflux/bootstrap/postgres"
|
||||
mflog "github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
mfsdk "github.com/mainflux/mainflux/pkg/sdk/go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
@ -39,6 +39,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
httpProtocol = "http"
|
||||
httpsProtocol = "https"
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -123,6 +127,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := mflog.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -147,19 +153,24 @@ func main() {
|
||||
auth := authapi.NewClient(authTracer, authConn, cfg.authTimeout)
|
||||
|
||||
svc := newService(auth, db, logger, esClient, cfg)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
go startHTTPServer(svc, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, svc, cfg, logger)
|
||||
})
|
||||
|
||||
go subscribeToThingsES(svc, thingsESConn, cfg.esConsumerName, logger)
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Bootstrap service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Bootstrap service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Bootstrap service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -320,16 +331,40 @@ func connectToAuth(cfg config, logger logger.Logger) *grpc.ClientConn {
|
||||
return conn
|
||||
}
|
||||
|
||||
func startHTTPServer(svc bootstrap.Service, cfg config, logger mflog.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, svc bootstrap.Service, cfg config, logger mflog.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.httpPort)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, bootstrap.NewConfigReader(cfg.encKey), logger)}
|
||||
errCh := make(chan error)
|
||||
protocol := httpProtocol
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("Bootstrap service started using https on port %s with cert %s key %s",
|
||||
cfg.httpPort, cfg.serverCert, cfg.serverKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, api.MakeHandler(svc, bootstrap.NewConfigReader(cfg.encKey), logger))
|
||||
return
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
protocol = httpsProtocol
|
||||
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Bootstrap service started using http on port %s", cfg.httpPort))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Bootstrap %s service error occurred during shutdown at %s: %s", protocol, p, err))
|
||||
return fmt.Errorf("bootstrap %s service error occurred during shutdown at %s: %w", protocol, p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Bootstrap %s service shutdown of http at %s", protocol, p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Bootstrap service started using http on port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, bootstrap.NewConfigReader(cfg.encKey), logger))
|
||||
}
|
||||
|
||||
func subscribeToThingsES(svc bootstrap.Service, client *r.Client, consumer string, logger mflog.Logger) {
|
||||
|
@ -4,16 +4,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -21,6 +20,7 @@ import (
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/readers/api"
|
||||
"github.com/mainflux/mainflux/readers/cassandra"
|
||||
@ -28,11 +28,14 @@ import (
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
svcName = "cassandra-reader"
|
||||
sep = ","
|
||||
defLogLevel = "error"
|
||||
@ -87,6 +90,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -113,18 +118,20 @@ func main() {
|
||||
|
||||
repo := newService(session, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, repo, tc, auth, cfg, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(repo, tc, auth, cfg, errs, logger)
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Cassandra reader service terminated: %s", err))
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Cassandra reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Cassandra reader service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func connectToAuth(cfg config, logger logger.Logger) *grpc.ClientConn {
|
||||
@ -279,14 +286,33 @@ func newService(session *gocql.Session, logger logger.Logger) readers.MessageRep
|
||||
return repo
|
||||
}
|
||||
|
||||
func startHTTPServer(repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, cfg config, errs chan error, logger logger.Logger) {
|
||||
func startHTTPServer(ctx context.Context, repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.port)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
logger.Info(fmt.Sprintf("Cassandra reader service started using https on port %s with cert %s key %s",
|
||||
cfg.port, cfg.serverCert, cfg.serverKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
return
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(repo, tc, ac, "cassandra-reader", logger)}
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("Cassandra reader service started using https on port %s with cert %s key %s", cfg.port, cfg.serverCert, cfg.serverKey))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Cassandra reader service started, exposed port %s", cfg.port))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Cassandra reader service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("cassandra reader service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Cassandra reader service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Cassandra reader service started, exposed port %s", cfg.port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
}
|
||||
|
@ -4,14 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/gocql/gocql"
|
||||
@ -20,13 +20,16 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/writers/api"
|
||||
"github.com/mainflux/mainflux/consumers/writers/cassandra"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "cassandra-writer"
|
||||
sep = ","
|
||||
svcName = "cassandra-writer"
|
||||
sep = ","
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
defLogLevel = "error"
|
||||
@ -59,6 +62,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -81,18 +86,19 @@ func main() {
|
||||
logger.Error(fmt.Sprintf("Failed to create Cassandra writer: %s", err))
|
||||
}
|
||||
|
||||
errs := make(chan error, 2)
|
||||
go startHTTPServer(ctx, cfg.port, logger)
|
||||
|
||||
go startHTTPServer(cfg.port, errs, logger)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Cassandra writer service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Cassandra writer service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Cassandra writer service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -150,8 +156,26 @@ func newService(session *gocql.Session, logger logger.Logger) consumers.Consumer
|
||||
return repo
|
||||
}
|
||||
|
||||
func startHTTPServer(port string, errs chan error, logger logger.Logger) {
|
||||
func startHTTPServer(ctx context.Context, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svcName)}
|
||||
logger.Info(fmt.Sprintf("Cassandra writer service started, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svcName))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Cassandra writer service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("cassandra writer service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Cassandra writer service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
@ -11,9 +12,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -27,6 +26,7 @@ import (
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
@ -38,6 +38,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -140,6 +142,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := mflog.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -172,18 +176,22 @@ func main() {
|
||||
auth := authapi.NewClient(authTracer, authConn, cfg.authTimeout)
|
||||
|
||||
svc := newService(auth, db, logger, nil, tlsCert, caCert, cfg, pkiClient)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
go startHTTPServer(svc, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, svc, cfg, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Certs service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Certs service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Certs service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -363,16 +371,36 @@ func newService(auth mainflux.AuthServiceClient, db *sqlx.DB, logger mflog.Logge
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(svc certs.Service, cfg config, logger mflog.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, svc certs.Service, cfg config, logger mflog.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.httpPort)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
logger.Info(fmt.Sprintf("Certs service started using https on port %s with cert %s key %s",
|
||||
cfg.httpPort, cfg.serverCert, cfg.serverKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, api.MakeHandler(svc, logger))
|
||||
return
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, logger)}
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("Certs service started using https on port %s with cert %s key %s", cfg.httpPort, cfg.serverCert, cfg.serverKey))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Certs service started using http on port %s", cfg.httpPort))
|
||||
go func() {
|
||||
errCh <- http.ListenAndServe(p, api.MakeHandler(svc, logger))
|
||||
}()
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Certs service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("certs service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Certs service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Certs service started using http on port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, logger))
|
||||
}
|
||||
|
||||
func loadCertificates(conf config) (tls.Certificate, *x509.Certificate, error) {
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -20,17 +19,21 @@ import (
|
||||
"github.com/mainflux/mainflux/coap"
|
||||
"github.com/mainflux/mainflux/coap/api"
|
||||
logger "github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
thingsapi "github.com/mainflux/mainflux/things/api/auth/grpc"
|
||||
broker "github.com/nats-io/nats.go"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
gocoap "github.com/plgd-dev/go-coap/v2"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defPort = "5683"
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
defLogLevel = "error"
|
||||
@ -63,6 +66,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -103,19 +108,25 @@ func main() {
|
||||
}, []string{"method"}),
|
||||
)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(cfg.port, logger, errs)
|
||||
go startCOAPServer(cfg, svc, nil, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startCOAPServer(ctx, cfg, svc, nil, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("CoAP adapter service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("CoAP adapter terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("CoAP adapter service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -189,14 +200,43 @@ func initJaeger(svcName, url string, logger logger.Logger) (opentracing.Tracer,
|
||||
return tracer, closer
|
||||
}
|
||||
|
||||
func startHTTPServer(port string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHTTPHandler()}
|
||||
logger.Info(fmt.Sprintf("CoAP service started, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHTTPHandler())
|
||||
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("CoAP adapter service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("CoAP adapter service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("CoAP adapter service shutdown at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func startCOAPServer(cfg config, svc coap.Service, auth mainflux.ThingsServiceClient, l logger.Logger, errs chan error) {
|
||||
func startCOAPServer(ctx context.Context, cfg config, svc coap.Service, auth mainflux.ThingsServiceClient, l logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.port)
|
||||
errCh := make(chan error)
|
||||
l.Info(fmt.Sprintf("CoAP adapter service started, exposed port %s", cfg.port))
|
||||
errs <- gocoap.ListenAndServe("udp", p, api.MakeCoAPHandler(svc, l))
|
||||
go func() {
|
||||
errCh <- gocoap.ListenAndServe("udp", p, api.MakeCoAPHandler(svc, l))
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
l.Info(fmt.Sprintf("CoAP adapter service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/credentials"
|
||||
@ -22,15 +21,19 @@ import (
|
||||
adapter "github.com/mainflux/mainflux/http"
|
||||
"github.com/mainflux/mainflux/http/api"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
thingsapi "github.com/mainflux/mainflux/things/api/auth/grpc"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defClientTLS = "false"
|
||||
defCACerts = ""
|
||||
@ -63,6 +66,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -105,22 +110,21 @@ func main() {
|
||||
}, []string{"method"}),
|
||||
)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, svc, cfg, logger, tracer)
|
||||
})
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("HTTP adapter service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
p := fmt.Sprintf(":%s", cfg.port)
|
||||
logger.Info(fmt.Sprintf("HTTP adapter service started on port %s", cfg.port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, tracer, logger))
|
||||
}()
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("HTTP adapter service terminated: %s", err))
|
||||
}
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("HTTP adapter terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -193,3 +197,27 @@ func connectToThings(cfg config, logger logger.Logger) *grpc.ClientConn {
|
||||
}
|
||||
return conn
|
||||
}
|
||||
|
||||
func startHTTPServer(ctx context.Context, svc adapter.Service, cfg config, logger logger.Logger, tracer opentracing.Tracer) error {
|
||||
p := fmt.Sprintf(":%s", cfg.port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, tracer, logger)}
|
||||
logger.Info(fmt.Sprintf("HTTP adapter service started on port %s", cfg.port))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("HTTP adapter service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("http adapter service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("HTTP adapter service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -17,6 +16,7 @@ import (
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/readers/api"
|
||||
"github.com/mainflux/mainflux/readers/influxdb"
|
||||
@ -24,11 +24,14 @@ import (
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
svcName = "influxdb-reader"
|
||||
defLogLevel = "error"
|
||||
defPort = "8180"
|
||||
@ -86,6 +89,9 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg, clientCfg := loadConfigs()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
log.Fatalf(err.Error())
|
||||
@ -115,17 +121,21 @@ func main() {
|
||||
|
||||
repo := newService(client, cfg.dbName, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, repo, tc, auth, cfg, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(repo, tc, auth, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("InfluxDB reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("InfluxDB writer service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("InfluxDB reader service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func connectToAuth(cfg config, logger logger.Logger) *grpc.ClientConn {
|
||||
@ -270,14 +280,35 @@ func newService(client influxdata.Client, dbName string, logger logger.Logger) r
|
||||
return repo
|
||||
}
|
||||
|
||||
func startHTTPServer(repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, cfg config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.port)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(repo, tc, ac, "influxdb-reader", logger)}
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("InfluxDB reader service started using https on port %s with cert %s key %s",
|
||||
cfg.port, cfg.serverCert, cfg.serverKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
return
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("InfluxDB reader service started, exposed port %s", cfg.port))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("InfluxDB reader service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("influxDB reader service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("InfluxDB reader service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("InfluxDB reader service started, exposed port %s", cfg.port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
influxdata "github.com/influxdata/influxdb/client/v2"
|
||||
@ -18,12 +18,15 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/writers/api"
|
||||
"github.com/mainflux/mainflux/consumers/writers/influxdb"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "influxdb-writer"
|
||||
svcName = "influxdb-writer"
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
defLogLevel = "error"
|
||||
@ -60,6 +63,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg, clientCfg := loadConfigs()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -91,17 +96,21 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
errs := make(chan error, 2)
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
return startHTTPService(ctx, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPService(cfg.port, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("InfluxDB reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("InfluxDB writer service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("InfluxDB reader service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfigs() (config, influxdata.HTTPConfig) {
|
||||
@ -144,8 +153,28 @@ func makeMetrics() (*kitprometheus.Counter, *kitprometheus.Summary) {
|
||||
return counter, latency
|
||||
}
|
||||
|
||||
func startHTTPService(port string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPService(ctx context.Context, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svcName)}
|
||||
|
||||
logger.Info(fmt.Sprintf("InfluxDB writer service started, exposed port %s", p))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svcName))
|
||||
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("InfluxDB writer service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("influxDB writer service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("InfluxDB writer service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
mqttPaho "github.com/eclipse/paho.mqtt.golang"
|
||||
@ -21,7 +19,9 @@ import (
|
||||
"github.com/mainflux/mainflux/lora"
|
||||
"github.com/mainflux/mainflux/lora/api"
|
||||
"github.com/mainflux/mainflux/lora/mqtt"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/mainflux/mainflux/lora/redis"
|
||||
@ -29,6 +29,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defHTTPPort = "8180"
|
||||
defLoraMsgURL = "tcp://localhost:1883"
|
||||
@ -86,6 +88,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -132,18 +136,22 @@ func main() {
|
||||
go subscribeToLoRaBroker(svc, mqttConn, cfg.loraMsgTimeout, cfg.loraMsgTopic, logger)
|
||||
go subscribeToThingsES(svc, esConn, cfg.esConsumerName, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, cfg, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("LoRa adapter shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("LoRa adapter terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("LoRa adapter terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -230,8 +238,29 @@ func newRouteMapRepository(client *r.Client, prefix string, logger logger.Logger
|
||||
return redis.NewRouteMapRepository(client, prefix)
|
||||
}
|
||||
|
||||
func startHTTPServer(cfg config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.httpPort)
|
||||
logger.Info(fmt.Sprintf("lora-adapter service started, exposed port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler())
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler()}
|
||||
|
||||
logger.Info(fmt.Sprintf("LoRa-adapter service started, exposed port %s", cfg.httpPort))
|
||||
|
||||
go func() {
|
||||
errCh <- http.ListenAndServe(p, api.MakeHandler())
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("LoRa-adapter service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("LoRa-adapter service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("LoRa-adapter service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,15 +11,14 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/readers/api"
|
||||
"github.com/mainflux/mainflux/readers/mongodb"
|
||||
@ -29,11 +28,14 @@ import (
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
svcName = "mongodb-reader"
|
||||
defLogLevel = "error"
|
||||
defPort = "8180"
|
||||
@ -85,6 +87,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfigs()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
log.Fatalf(err.Error())
|
||||
@ -110,17 +114,22 @@ func main() {
|
||||
|
||||
repo := newService(db, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, repo, tc, auth, cfg, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(repo, tc, auth, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("MongoDB reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("MongoDB reader service terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("MongoDB reader service terminated: %s", err))
|
||||
}
|
||||
|
||||
func connectToAuth(cfg config, logger logger.Logger) *grpc.ClientConn {
|
||||
@ -265,14 +274,36 @@ func newService(db *mongo.Database, logger logger.Logger) readers.MessageReposit
|
||||
return repo
|
||||
}
|
||||
|
||||
func startHTTPServer(repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, cfg config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.port)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(repo, tc, ac, "mongodb-reader", logger)}
|
||||
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("Mongo reader service started using https on port %s with cert %s key %s",
|
||||
cfg.port, cfg.serverCert, cfg.serverKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
return
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Mongo reader service started, exposed port %s", cfg.port))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("MongoDB reader service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("mongodb reader service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("MongoDB reader service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Mongo reader service started, exposed port %s", cfg.port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
}
|
||||
|
@ -9,8 +9,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/mainflux/mainflux"
|
||||
@ -18,14 +17,17 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/writers/api"
|
||||
"github.com/mainflux/mainflux/consumers/writers/mongodb"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "mongodb-writer"
|
||||
svcName = "mongodb-writer"
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
@ -56,6 +58,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfigs()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -88,17 +92,22 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
errs := make(chan error, 2)
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
return startHTTPService(ctx, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPService(cfg.port, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("MongoDB reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("MongoDB writer service terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("MongoDB writer service terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfigs() config {
|
||||
@ -131,8 +140,29 @@ func makeMetrics() (*kitprometheus.Counter, *kitprometheus.Summary) {
|
||||
return counter, latency
|
||||
}
|
||||
|
||||
func startHTTPService(port string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPService(ctx context.Context, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
logger.Info(fmt.Sprintf("Mongodb writer service started, exposed port %s", p))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svcName))
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svcName)}
|
||||
|
||||
logger.Info(fmt.Sprintf("MongoDB writer service started, exposed port %s", p))
|
||||
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("MongoDB writer service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("mongodb writer service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("MongoDB writer service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
@ -29,6 +28,7 @@ import (
|
||||
ws "github.com/mainflux/mproxy/pkg/websocket"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
@ -121,6 +121,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := mflog.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -185,22 +187,27 @@ func main() {
|
||||
// Event handler for MQTT hooks
|
||||
h := mqtt.NewHandler([]messaging.Publisher{np}, es, logger, authClient)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
|
||||
logger.Info(fmt.Sprintf("Starting MQTT proxy on port %s", cfg.mqttPort))
|
||||
go proxyMQTT(cfg, logger, h, errs)
|
||||
g.Go(func() error {
|
||||
return proxyMQTT(ctx, cfg, logger, h)
|
||||
})
|
||||
|
||||
logger.Info(fmt.Sprintf("Starting MQTT over WS proxy on port %s", cfg.httpPort))
|
||||
go proxyWS(cfg, logger, h, errs)
|
||||
g.Go(func() error {
|
||||
return proxyWS(ctx, cfg, logger, h)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("mProxy shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("mProxy terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("mProxy terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -309,19 +316,43 @@ func connectToRedis(redisURL, redisPass, redisDB string, logger mflog.Logger) *r
|
||||
})
|
||||
}
|
||||
|
||||
func proxyMQTT(cfg config, logger mflog.Logger, handler session.Handler, errs chan error) {
|
||||
func proxyMQTT(ctx context.Context, cfg config, logger mflog.Logger, handler session.Handler) error {
|
||||
address := fmt.Sprintf(":%s", cfg.mqttPort)
|
||||
target := fmt.Sprintf("%s:%s", cfg.mqttTargetHost, cfg.mqttTargetPort)
|
||||
mp := mp.New(address, target, handler, logger)
|
||||
|
||||
errs <- mp.Listen()
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
errCh <- mp.Listen()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Info(fmt.Sprintf("proxy MQTT shutdown at %s", target))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
func proxyWS(cfg config, logger mflog.Logger, handler session.Handler, errs chan error) {
|
||||
func proxyWS(ctx context.Context, cfg config, logger mflog.Logger, handler session.Handler) error {
|
||||
target := fmt.Sprintf("%s:%s", cfg.httpTargetHost, cfg.httpTargetPort)
|
||||
wp := ws.New(target, cfg.httpTargetPath, "ws", handler, logger)
|
||||
http.Handle("/mqtt", wp.Handler())
|
||||
|
||||
errs <- wp.Listen(cfg.httpPort)
|
||||
errCh := make(chan error)
|
||||
|
||||
go func() {
|
||||
errCh <- wp.Listen(cfg.httpPort)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Info(fmt.Sprintf("proxy MQTT WS shutdown at %s", target))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func healthcheck(cfg config) func() error {
|
||||
|
@ -9,9 +9,8 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
r "github.com/go-redis/redis/v8"
|
||||
"github.com/mainflux/mainflux"
|
||||
@ -21,13 +20,17 @@ import (
|
||||
"github.com/mainflux/mainflux/opcua/db"
|
||||
"github.com/mainflux/mainflux/opcua/gopcua"
|
||||
"github.com/mainflux/mainflux/opcua/redis"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defHTTPPort = "8180"
|
||||
defOPCIntervalMs = "1000"
|
||||
@ -81,6 +84,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
httpCtx, httpCancel := context.WithCancel(context.Background())
|
||||
g, httpCtx := errgroup.WithContext(httpCtx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -129,18 +134,21 @@ func main() {
|
||||
go subscribeToStoredSubs(sub, cfg.opcuaConfig, logger)
|
||||
go subscribeToThingsES(svc, esConn, cfg.esConsumerName, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(httpCtx, svc, cfg, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(svc, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(httpCtx); sig != nil {
|
||||
httpCancel()
|
||||
logger.Info(fmt.Sprintf("OPC-UA adapter service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("OPC-UA adapter terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("OPC-UA adapter service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -216,8 +224,28 @@ func newRouteMapRepositoy(client *r.Client, prefix string, logger logger.Logger)
|
||||
return redis.NewRouteMapRepository(client, prefix)
|
||||
}
|
||||
|
||||
func startHTTPServer(svc opcua.Service, cfg config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, svc opcua.Service, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.httpPort)
|
||||
logger.Info(fmt.Sprintf("opcua-adapter service started, exposed port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, logger))
|
||||
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, logger)}
|
||||
logger.Info(fmt.Sprintf("OPC-UA adapter service started, exposed port %s", cfg.httpPort))
|
||||
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("OPC-UA adapter service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("OPC-UA adapter service error occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("OPC-UA adapter service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -20,6 +19,7 @@ import (
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/readers/api"
|
||||
"github.com/mainflux/mainflux/readers/postgres"
|
||||
@ -27,13 +27,15 @@ import (
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "postgres-reader"
|
||||
sep = ","
|
||||
svcName = "postgres-reader"
|
||||
sep = ","
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defPort = "8180"
|
||||
@ -89,6 +91,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -116,18 +120,21 @@ func main() {
|
||||
|
||||
repo := newService(db, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, repo, tc, auth, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(repo, tc, auth, cfg.port, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Postgres reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Postgres reader service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Postgres reader service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func connectToAuth(cfg config, logger logger.Logger) *grpc.ClientConn {
|
||||
@ -278,8 +285,27 @@ func newService(db *sqlx.DB, logger logger.Logger) readers.MessageRepository {
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, port string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(repo, tc, ac, svcName, logger)}
|
||||
|
||||
logger.Info(fmt.Sprintf("Postgres reader service started, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Postgres reader service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("postgres reader service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Postgres reader service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@ -18,13 +18,16 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/writers/api"
|
||||
"github.com/mainflux/mainflux/consumers/writers/postgres"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "postgres-writer"
|
||||
sep = ","
|
||||
svcName = "postgres-writer"
|
||||
sep = ","
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
@ -65,6 +68,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -87,18 +92,22 @@ func main() {
|
||||
logger.Error(fmt.Sprintf("Failed to create Postgres writer: %s", err))
|
||||
}
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(cfg.port, errs, logger)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Postgres writer service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Postgres writer service terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Postgres writer service terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -154,8 +163,27 @@ func newService(db *sqlx.DB, logger logger.Logger) consumers.Consumer {
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(port string, errs chan error, logger logger.Logger) {
|
||||
func startHTTPServer(ctx context.Context, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svcName)}
|
||||
|
||||
logger.Info(fmt.Sprintf("Postgres writer service started, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svcName))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Postgres writer service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("postgres writer service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Postgres writer service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
@ -18,10 +18,13 @@ import (
|
||||
"github.com/mainflux/mainflux/provision"
|
||||
"github.com/mainflux/mainflux/provision/api"
|
||||
"github.com/mainflux/mainflux/things"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
defLogLevel = "debug"
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defConfigFile = "config.toml"
|
||||
defTLS = "false"
|
||||
defServerCert = ""
|
||||
@ -79,6 +82,9 @@ var (
|
||||
|
||||
func main() {
|
||||
cfg, err := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf(err.Error())
|
||||
}
|
||||
@ -107,30 +113,56 @@ func main() {
|
||||
svc := provision.New(cfg, SDK, logger)
|
||||
svc = api.NewLoggingMiddleware(svc, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, svc, cfg, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(svc, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Provision service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Provision service terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Provision service terminated: %s", err))
|
||||
}
|
||||
|
||||
func startHTTPServer(svc provision.Service, cfg provision.Config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, svc provision.Service, cfg provision.Config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.Server.HTTPPort)
|
||||
if cfg.Server.ServerCert != "" || cfg.Server.ServerKey != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, logger)}
|
||||
|
||||
switch {
|
||||
case cfg.Server.ServerCert != "" || cfg.Server.ServerKey != "":
|
||||
logger.Info(fmt.Sprintf("Provision service started using https on port %s with cert %s key %s",
|
||||
cfg.Server.HTTPPort, cfg.Server.ServerCert, cfg.Server.ServerKey))
|
||||
errs <- http.ListenAndServeTLS(p, cfg.Server.ServerCert, cfg.Server.ServerKey, api.MakeHandler(svc, logger))
|
||||
return
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.Server.ServerCert, cfg.Server.ServerKey)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Provision service started using http on port %s", cfg.Server.HTTPPort))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Provision service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("provision service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Provision service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Provision service started using http on port %s", cfg.Server.HTTPPort))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, logger))
|
||||
}
|
||||
|
||||
func loadConfigFromFile(file string) (provision.Config, error) {
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -23,10 +22,12 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/notifiers"
|
||||
"github.com/mainflux/mainflux/consumers/notifiers/api"
|
||||
"github.com/mainflux/mainflux/consumers/notifiers/postgres"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
mfsmpp "github.com/mainflux/mainflux/consumers/notifiers/smpp"
|
||||
"github.com/mainflux/mainflux/consumers/notifiers/tracing"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
"github.com/mainflux/mainflux/pkg/ulid"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
@ -37,6 +38,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -121,6 +124,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -152,22 +157,27 @@ func main() {
|
||||
defer dbCloser.Close()
|
||||
|
||||
svc := newService(db, dbTracer, auth, cfg, logger)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
if err = consumers.Start(pubSub, svc, cfg.configPath, logger); err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to create Postgres writer: %s", err))
|
||||
}
|
||||
|
||||
go startHTTPServer(tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("SMPP notifier service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("SMPP notifier service terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Users service terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -323,13 +333,36 @@ func newService(db *sqlx.DB, tracer opentracing.Tracer, auth mainflux.AuthServic
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(tracer opentracing.Tracer, svc notifiers.Service, port string, certFile string, keyFile string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, tracer opentracing.Tracer, svc notifiers.Service, port string, certFile string, keyFile string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if certFile != "" || keyFile != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, tracer, logger)}
|
||||
|
||||
switch {
|
||||
case certFile != "" || keyFile != "":
|
||||
logger.Info(fmt.Sprintf("SMPP notifier service started using https, cert %s key %s, exposed port %s", certFile, keyFile, port))
|
||||
errs <- http.ListenAndServeTLS(p, certFile, keyFile, api.MakeHandler(svc, tracer, logger))
|
||||
} else {
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(certFile, keyFile)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("SMPP notifier service started using http, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, tracer, logger))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("SMPP notifier service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("smpp notifier service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("SMPP notifier service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -27,16 +26,20 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/notifiers/tracing"
|
||||
"github.com/mainflux/mainflux/internal/email"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
"github.com/mainflux/mainflux/pkg/ulid"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -119,6 +122,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -150,22 +155,27 @@ func main() {
|
||||
defer dbCloser.Close()
|
||||
|
||||
svc := newService(db, dbTracer, auth, cfg, logger)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
if err = consumers.Start(pubSub, svc, cfg.configPath, logger); err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to create Postgres writer: %s", err))
|
||||
}
|
||||
|
||||
go startHTTPServer(tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("SMTP notifier service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("SMTP notifier service terminated: %s", err))
|
||||
}
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Users service terminated: %s", err))
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -310,13 +320,35 @@ func newService(db *sqlx.DB, tracer opentracing.Tracer, auth mainflux.AuthServic
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(tracer opentracing.Tracer, svc notifiers.Service, port string, certFile string, keyFile string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, tracer opentracing.Tracer, svc notifiers.Service, port string, certFile string, keyFile string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if certFile != "" || keyFile != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, tracer, logger)}
|
||||
|
||||
switch {
|
||||
case certFile != "" || keyFile != "":
|
||||
logger.Info(fmt.Sprintf("SMTP notifier service started using https, cert %s key %s, exposed port %s", certFile, keyFile, port))
|
||||
errs <- http.ListenAndServeTLS(p, certFile, keyFile, api.MakeHandler(svc, tracer, logger))
|
||||
} else {
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(certFile, keyFile)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("SMTP notifier service started using http, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, tracer, logger))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("SMTP notifier service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("smtp notifier service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("SMTP notifier service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -11,9 +12,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -22,6 +21,7 @@ import (
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/uuid"
|
||||
"github.com/mainflux/mainflux/things"
|
||||
"github.com/mainflux/mainflux/things/api"
|
||||
@ -35,11 +35,14 @@ import (
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -124,6 +127,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -155,20 +160,30 @@ func main() {
|
||||
defer cacheCloser.Close()
|
||||
|
||||
svc := newService(auth, dbTracer, cacheTracer, db, cacheClient, esClient, logger)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
go startHTTPServer(thhttpapi.MakeHandler(thingsTracer, svc, logger), cfg.httpPort, cfg, logger, errs)
|
||||
go startHTTPServer(authhttpapi.MakeHandler(thingsTracer, svc, logger), cfg.authHTTPPort, cfg, logger, errs)
|
||||
go startGRPCServer(svc, thingsTracer, cfg, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, "thing-http", thhttpapi.MakeHandler(thingsTracer, svc, logger), cfg.httpPort, cfg, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, "auth-http", authhttpapi.MakeHandler(thingsTracer, svc, logger), cfg.authHTTPPort, cfg, logger)
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Things service terminated: %s", err))
|
||||
g.Go(func() error {
|
||||
return startGRPCServer(ctx, svc, thingsTracer, cfg, logger)
|
||||
})
|
||||
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Things service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Things service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -336,41 +351,84 @@ func newService(auth mainflux.AuthServiceClient, dbTracer opentracing.Tracer, ca
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(handler http.Handler, port string, cfg config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, typ string, handler http.Handler, port string, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
logger.Info(fmt.Sprintf("Things 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
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: handler}
|
||||
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("Things %s service started using https on port %s with cert %s key %s",
|
||||
typ, port, cfg.serverCert, cfg.serverKey))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Things %s service started using http on port %s", typ, cfg.httpPort))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Things service started using http on port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, handler)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Things %s service error occurred during shutdown at %s: %s", typ, p, err))
|
||||
return fmt.Errorf("things %s service occurred during shutdown at %s: %w", typ, p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Things %s service shutdown of http at %s", typ, p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func startGRPCServer(svc things.Service, tracer opentracing.Tracer, cfg config, logger logger.Logger, errs chan error) {
|
||||
func startGRPCServer(ctx context.Context, svc things.Service, tracer opentracing.Tracer, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", cfg.authGRPCPort)
|
||||
errCh := make(chan error)
|
||||
var server *grpc.Server
|
||||
|
||||
listener, err := net.Listen("tcp", p)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to listen on port %s: %s", cfg.authGRPCPort, err))
|
||||
os.Exit(1)
|
||||
return fmt.Errorf("failed to listen on port %s: %w", cfg.authGRPCPort, err)
|
||||
}
|
||||
|
||||
var server *grpc.Server
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
creds, err := credentials.NewServerTLSFromFile(cfg.serverCert, cfg.serverKey)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to load things certificates: %s", err))
|
||||
os.Exit(1)
|
||||
return fmt.Errorf("failed to load things certificates: %w", err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Things gRPC service started using https on port %s with cert %s key %s",
|
||||
cfg.authGRPCPort, cfg.serverCert, cfg.serverKey))
|
||||
server = grpc.NewServer(grpc.Creds(creds))
|
||||
} else {
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Things gRPC service started using http on port %s", cfg.authGRPCPort))
|
||||
server = grpc.NewServer()
|
||||
}
|
||||
|
||||
mainflux.RegisterThingsServiceServer(server, authgrpcapi.NewServer(tracer, svc))
|
||||
errs <- server.Serve(listener)
|
||||
go func() {
|
||||
errCh <- server.Serve(listener)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
c := make(chan bool)
|
||||
go func() {
|
||||
defer close(c)
|
||||
server.GracefulStop()
|
||||
}()
|
||||
select {
|
||||
case <-c:
|
||||
case <-time.After(stopWaitTime):
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Things gRPC service shutdown at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -20,6 +19,7 @@ import (
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/readers/api"
|
||||
"github.com/mainflux/mainflux/readers/timescale"
|
||||
@ -27,12 +27,14 @@ import (
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "timescaledb-reader"
|
||||
svcName = "timescaledb-reader"
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defPort = "8911"
|
||||
@ -84,6 +86,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -110,18 +114,21 @@ func main() {
|
||||
|
||||
repo := newService(db, logger)
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, repo, tc, auth, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(repo, tc, auth, cfg.port, logger, errs)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Timescale reader service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Timescale reader service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Timescale reader service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -264,8 +271,27 @@ func newService(db *sqlx.DB, logger logger.Logger) readers.MessageRepository {
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, port string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, repo readers.MessageRepository, tc mainflux.ThingsServiceClient, ac mainflux.AuthServiceClient, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(repo, tc, ac, svcName, logger)}
|
||||
|
||||
logger.Info(fmt.Sprintf("Timescale reader service started, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(repo, tc, ac, svcName, logger))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Timescale reader service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("Timescale reader service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Timescale reader service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@ -19,12 +18,15 @@ import (
|
||||
"github.com/mainflux/mainflux/consumers/writers/api"
|
||||
"github.com/mainflux/mainflux/consumers/writers/timescale"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "timescaledb-writer"
|
||||
svcName = "timescaledb-writer"
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
@ -65,6 +67,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -87,18 +91,21 @@ func main() {
|
||||
logger.Error(fmt.Sprintf("Failed to create Timescale writer: %s", err))
|
||||
}
|
||||
|
||||
errs := make(chan error, 2)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, cfg.port, logger)
|
||||
})
|
||||
|
||||
go startHTTPServer(cfg.port, errs, logger)
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Timescale writer service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Timescale writer service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Timescale writer service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -154,8 +161,28 @@ func newService(db *sqlx.DB, logger logger.Logger) consumers.Consumer {
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(port string, errs chan error, logger logger.Logger) {
|
||||
func startHTTPServer(ctx context.Context, port string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svcName)}
|
||||
|
||||
logger.Info(fmt.Sprintf("Timescale writer service started, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svcName))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("timescale writer service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("timescale writer service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Timescale writer service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,15 +4,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
|
||||
@ -20,6 +19,7 @@ import (
|
||||
"github.com/mainflux/mainflux"
|
||||
authapi "github.com/mainflux/mainflux/auth/api/grpc"
|
||||
"github.com/mainflux/mainflux/logger"
|
||||
"github.com/mainflux/mainflux/pkg/errors"
|
||||
"github.com/mainflux/mainflux/pkg/messaging"
|
||||
"github.com/mainflux/mainflux/pkg/messaging/nats"
|
||||
"github.com/mainflux/mainflux/pkg/uuid"
|
||||
@ -34,12 +34,14 @@ import (
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
jconfig "github.com/uber/jaeger-client-go/config"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
queue = "twins"
|
||||
queue = "twins"
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defHTTPPort = "8180"
|
||||
@ -105,6 +107,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -138,17 +142,22 @@ func main() {
|
||||
|
||||
tracer, closer := initJaeger("twins", cfg.jaegerURL, logger)
|
||||
defer closer.Close()
|
||||
errs := make(chan error, 2)
|
||||
go startHTTPServer(twapi.MakeHandler(tracer, svc, logger), cfg.httpPort, cfg, logger, errs)
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, twapi.MakeHandler(tracer, svc, logger), cfg.httpPort, cfg, logger)
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Twins service terminated: %s", err))
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Twins service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Twins service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -310,14 +319,36 @@ func newService(ps messaging.PubSub, chanID string, users mainflux.AuthServiceCl
|
||||
return svc
|
||||
}
|
||||
|
||||
func startHTTPServer(handler http.Handler, port string, cfg config, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, handler http.Handler, port string, cfg config, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if cfg.serverCert != "" || cfg.serverKey != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: handler}
|
||||
|
||||
switch {
|
||||
case cfg.serverCert != "" || cfg.serverKey != "":
|
||||
logger.Info(fmt.Sprintf("Twins 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
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(cfg.serverCert, cfg.serverKey)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Twins service started using http on port %s", cfg.httpPort))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Twins service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("twins service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Twins service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Twins service started using http on port %s", cfg.httpPort))
|
||||
errs <- http.ListenAndServe(p, handler)
|
||||
}
|
||||
|
@ -11,10 +11,8 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/mainflux/mainflux/internal/email"
|
||||
@ -24,6 +22,7 @@ import (
|
||||
"github.com/mainflux/mainflux/users/bcrypt"
|
||||
"github.com/mainflux/mainflux/users/emailer"
|
||||
"github.com/mainflux/mainflux/users/tracing"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
@ -40,6 +39,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
stopWaitTime = 5 * time.Second
|
||||
|
||||
defLogLevel = "error"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
@ -135,6 +136,8 @@ type config struct {
|
||||
|
||||
func main() {
|
||||
cfg := loadConfig()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
logger, err := logger.New(os.Stdout, cfg.logLevel)
|
||||
if err != nil {
|
||||
@ -158,18 +161,22 @@ func main() {
|
||||
defer dbCloser.Close()
|
||||
|
||||
svc := newService(db, dbTracer, auth, cfg, logger)
|
||||
errs := make(chan error, 2)
|
||||
|
||||
go startHTTPServer(tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger, errs)
|
||||
g.Go(func() error {
|
||||
return startHTTPServer(ctx, tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger)
|
||||
})
|
||||
|
||||
go func() {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
errs <- fmt.Errorf("%s", <-c)
|
||||
}()
|
||||
g.Go(func() error {
|
||||
if sig := errors.SignalHandler(ctx); sig != nil {
|
||||
cancel()
|
||||
logger.Info(fmt.Sprintf("Users service shutdown by signal: %s", sig))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
err = <-errs
|
||||
logger.Error(fmt.Sprintf("Users service terminated: %s", err))
|
||||
if err := g.Wait(); err != nil {
|
||||
logger.Error(fmt.Sprintf("Users service terminated: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig() config {
|
||||
@ -411,13 +418,36 @@ func createAdmin(svc users.Service, userRepo users.UserRepository, c config, aut
|
||||
return nil
|
||||
}
|
||||
|
||||
func startHTTPServer(tracer opentracing.Tracer, svc users.Service, port string, certFile string, keyFile string, logger logger.Logger, errs chan error) {
|
||||
func startHTTPServer(ctx context.Context, tracer opentracing.Tracer, svc users.Service, port string, certFile string, keyFile string, logger logger.Logger) error {
|
||||
p := fmt.Sprintf(":%s", port)
|
||||
if certFile != "" || keyFile != "" {
|
||||
errCh := make(chan error)
|
||||
server := &http.Server{Addr: p, Handler: api.MakeHandler(svc, tracer, logger)}
|
||||
|
||||
switch {
|
||||
case certFile != "" || keyFile != "":
|
||||
logger.Info(fmt.Sprintf("Users service started using https, cert %s key %s, exposed port %s", certFile, keyFile, port))
|
||||
errs <- http.ListenAndServeTLS(p, certFile, keyFile, api.MakeHandler(svc, tracer, logger))
|
||||
} else {
|
||||
go func() {
|
||||
errCh <- server.ListenAndServeTLS(certFile, keyFile)
|
||||
}()
|
||||
default:
|
||||
logger.Info(fmt.Sprintf("Users service started using http, exposed port %s", port))
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, tracer, logger))
|
||||
go func() {
|
||||
errCh <- server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
ctxShutdown, cancelShutdown := context.WithTimeout(context.Background(), stopWaitTime)
|
||||
defer cancelShutdown()
|
||||
if err := server.Shutdown(ctxShutdown); err != nil {
|
||||
logger.Error(fmt.Sprintf("Users service error occurred during shutdown at %s: %s", p, err))
|
||||
return fmt.Errorf("users service occurred during shutdown at %s: %w", p, err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("Users service shutdown of http at %s", p))
|
||||
return nil
|
||||
case err := <-errCh:
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,14 @@
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Error specifies an API that must be fullfiled by error type
|
||||
type Error interface {
|
||||
|
||||
@ -94,3 +102,14 @@ func New(text string) Error {
|
||||
err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func SignalHandler(ctx context.Context) error {
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, syscall.SIGINT, syscall.SIGABRT)
|
||||
select {
|
||||
case sig := <-c:
|
||||
return fmt.Errorf("%s", sig)
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user