From 14145d3dea5a550170faf78549382c1825a840e2 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Tue, 29 Nov 2022 22:35:02 +0100 Subject: [PATCH 01/18] Huge refactoring --- .drone.yml | 62 ++++ .env.dist | 4 + Dockerfile.server | 30 ++ Dockerfile.worker | 30 ++ Makefile | 19 ++ README.md | 4 +- cmd/main.go | 7 - deploy/image-build.sh | 31 ++ deploy/image-push.sh | 10 + .gitignore => src/.gitignore | 4 +- src/cmd/server/main.go | 72 +++++ src/cmd/worker/main.go | 130 ++++++++ src/go.mod | 49 +++ src/go.sum | 333 ++++++++++++++++++++ src/internal/app/config/env.go | 22 ++ src/internal/app/database/connect.go | 16 + src/internal/app/definition/error.go | 9 + src/internal/app/definition/health.go | 5 + src/internal/app/definition/order_status.go | 8 + src/internal/app/event/email.go | 7 + src/internal/app/event/event.go | 12 + src/internal/app/server/config.go | 15 + src/internal/app/server/health_handler.go | 13 + src/internal/app/server/order_handler.go | 30 ++ src/internal/app/server/router.go | 31 ++ src/internal/app/server/server.go | 101 ++++++ src/internal/app/service/order.go | 27 ++ src/pkg/amqp/connect.go | 26 ++ src/pkg/amqp/pubsub.go | 88 ++++++ src/pkg/consul/discovery.go | 107 +++++++ src/pkg/fluentd/config.go | 14 + src/pkg/fluentd/logger.go | 41 +++ 32 files changed, 1346 insertions(+), 11 deletions(-) create mode 100644 .drone.yml create mode 100644 .env.dist create mode 100644 Dockerfile.server create mode 100644 Dockerfile.worker create mode 100644 Makefile delete mode 100644 cmd/main.go create mode 100755 deploy/image-build.sh create mode 100755 deploy/image-push.sh rename .gitignore => src/.gitignore (95%) create mode 100644 src/cmd/server/main.go create mode 100644 src/cmd/worker/main.go create mode 100644 src/go.mod create mode 100644 src/go.sum create mode 100644 src/internal/app/config/env.go create mode 100644 src/internal/app/database/connect.go create mode 100644 src/internal/app/definition/error.go create mode 100644 src/internal/app/definition/health.go create mode 100644 src/internal/app/definition/order_status.go create mode 100644 src/internal/app/event/email.go create mode 100644 src/internal/app/event/event.go create mode 100644 src/internal/app/server/config.go create mode 100644 src/internal/app/server/health_handler.go create mode 100644 src/internal/app/server/order_handler.go create mode 100644 src/internal/app/server/router.go create mode 100644 src/internal/app/server/server.go create mode 100644 src/internal/app/service/order.go create mode 100644 src/pkg/amqp/connect.go create mode 100644 src/pkg/amqp/pubsub.go create mode 100644 src/pkg/consul/discovery.go create mode 100644 src/pkg/fluentd/config.go create mode 100644 src/pkg/fluentd/logger.go diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..303b906 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,62 @@ +kind: pipeline +type: docker +name: default + +steps: +- name: static_check + image: golang:latest + commands: + - go install honnef.co/go/tools/cmd/staticcheck@latest + - cd src && staticcheck ./... + volumes: + - name: gopath + path: /go + +- name: lint + image: golang:latest + commands: + - go install golang.org/x/lint/golint@latest + - golint ./src/... + volumes: + - name: gopath + path: /go + +- name: analyze + image: golang:latest + commands: + - cd src && go vet ./... + volumes: + - name: gopath + path: /go + +- name: publish_image + image: plugins/docker + environment: + DOCKER_USERNAME: + from_secret: registry_username + DOCKER_PASSWORD: + from_secret: registry_password + commands: + - sleep 5 + - ./deploy/image-build.sh + - ./deploy/image-push.sh + volumes: + - name: docker-sock + path: /var/run + when: + branch: + - main + +services: +- name: docker + image: docker:dind + privileged: true + volumes: + - name: docker-sock + path: /var/run + +volumes: +- name: gopath + temp: {} +- name: docker-sock + temp: {} diff --git a/.env.dist b/.env.dist new file mode 100644 index 0000000..84c5d45 --- /dev/null +++ b/.env.dist @@ -0,0 +1,4 @@ +SERVER_ADDR=:80 +DATABASE_URL=postgres://postgres:12345678@postgres-db:5432/egommerce +MONGODB_URL=mongodb://mongodb:12345678@mongo-db:27017 +EVENTBUS_URL=amqp://guest:guest@api-eventbus:5672 \ No newline at end of file diff --git a/Dockerfile.server b/Dockerfile.server new file mode 100644 index 0000000..e566008 --- /dev/null +++ b/Dockerfile.server @@ -0,0 +1,30 @@ +# Builder +FROM golang:alpine AS builder + +ARG BIN_OUTPUT=/go/bin/server +ARG GO_MAIN=cmd/server/main.go + +WORKDIR /go/src/app +COPY src ./ + +RUN go mod download && \ + export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ + go build -ldflags="-w -s" -o $BIN_OUTPUT $GO_MAIN + + +# Destination image - server +FROM gcr.io/distroless/base-debian10 + +ARG BIN_OUTPUT=/go/bin/server + +LABEL author="Piotr Biernat" +LABEL service="order-svc" +LABEL vendor="Egommerce" +LABEL version="1.0" + +WORKDIR / +COPY --from=builder $BIN_OUTPUT / +COPY .env.dist /.env + +EXPOSE 80 +ENTRYPOINT ["/server"] diff --git a/Dockerfile.worker b/Dockerfile.worker new file mode 100644 index 0000000..cadfd07 --- /dev/null +++ b/Dockerfile.worker @@ -0,0 +1,30 @@ +# Builder +FROM golang:alpine AS builder + +ARG BIN_OUTPUT=/go/bin/worker +ARG GO_WORKER=cmd/worker/main.go + +WORKDIR /go/src/app +COPY src ./ + +RUN go mod download && \ + export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ + go build -ldflags="-w -s" -o $BIN_OUTPUT $GO_WORKER + + +# Destination image - worker +FROM gcr.io/distroless/base-debian10 + +ARG BIN_OUTPUT=/go/bin/worker + +LABEL author="Piotr Biernat" +LABEL service="order-worker" +LABEL vendor="Egommerce" +LABEL version="1.0" + +WORKDIR / +COPY --from=builder $BIN_OUTPUT / +COPY .env.dist /.env + +EXPOSE 80 +ENTRYPOINT ["/worker"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2d234f9 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +DEPLOY_DIR := ./deploy +SRC_DIR := ./src + +## DEPLOY PART +build-image-dev: + - sh ${DEPLOY_DIR}/image-build.sh dev + +build-image-prod: + - sh ${DEPLOY_DIR}/image-build.sh + +push-image-prod: + - sh ${DEPLOY_DIR}/image-push.sh + +# (GOLANG) APP PART +app-run: + - make -C ${SRC_DIR} run + +app-build: + - make -C ${SRC_DIR} build diff --git a/README.md b/README.md index ad621a9..86c6c08 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# ordering-service +# order-service -Ordering service \ No newline at end of file +Order service \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go deleted file mode 100644 index 8777b4b..0000000 --- a/cmd/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "fmt" - -func main() { - fmt.Println("Ordering services") -} diff --git a/deploy/image-build.sh b/deploy/image-build.sh new file mode 100755 index 0000000..4cba8d4 --- /dev/null +++ b/deploy/image-build.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# RUN IN REPO ROOT DIR !! + +export IMAGE_BASE="git.pbiernat.dev/egommerce/order" +export SERVER_IMAGE="$IMAGE_BASE-svc" +export WORKER_IMAGE="$IMAGE_BASE-worker" + +TARGET=${1:-latest} +KIND=${2:-all} + +if [ $KIND = "svc" ] || [ $KIND = "all" ]; then + echo "Building: $SERVER_IMAGE:$TARGET" + if [ $TARGET = "dev" ] + then + docker build --rm --no-cache -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.server . # >/dev/null 2>&1 + else + docker build --rm --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.server . >/dev/null 2>&1 + fi +fi + +if [ $KIND = "worker" ] || [ $KIND = "all" ]; then + echo "Building: $WORKER_IMAGE:$TARGET" + if [ $TARGET = "dev" ] + then + docker build --rm --no-cache -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.worker . # >/dev/null 2>&1 + else + docker build --rm --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.worker . >/dev/null 2>&1 + fi +fi +echo "Done." + diff --git a/deploy/image-push.sh b/deploy/image-push.sh new file mode 100755 index 0000000..a4e3f11 --- /dev/null +++ b/deploy/image-push.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# RUN IN REPO ROOT DIR !! + +export IMAGE_BASE="git.pbiernat.dev/egommerce/order" +export SERVER_IMAGE="$IMAGE_BASE-svc" +export WORKER_IMAGE="$IMAGE_BASE-worker" + +echo $DOCKER_PASSWORD | docker login git.pbiernat.dev -u $DOCKER_USERNAME --password-stdin +docker push "$SERVER_IMAGE:latest" +docker push "$WORKER_IMAGE:latest" diff --git a/.gitignore b/src/.gitignore similarity index 95% rename from .gitignore rename to src/.gitignore index f4d432a..47de0bc 100644 --- a/.gitignore +++ b/src/.gitignore @@ -12,6 +12,6 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out +.env # Dependency directories (remove the comment below to include it) -# vendor/ - +vendor/ diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go new file mode 100644 index 0000000..51fa063 --- /dev/null +++ b/src/cmd/server/main.go @@ -0,0 +1,72 @@ +package main + +import ( + "log" + "os" + "strconv" + + "git.pbiernat.dev/egommerce/order-service/internal/app/config" + "git.pbiernat.dev/egommerce/order-service/internal/app/database" + "git.pbiernat.dev/egommerce/order-service/internal/app/server" + "git.pbiernat.dev/egommerce/order-service/pkg/amqp" + "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" +) + +const ( + defAppName = "order-svc" + defAppDomain = "order-svc" + defNetAddr = ":80" + defLoggerAddr = "api-logger:24224" + defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" + defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" + defEventBusURL = "amqp://guest:guest@api-eventbus:5672" + ebEventsExchange = "api-events" + ebEventsQueue = "order-svc" +) + +func main() { + if config.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + } + + c := new(server.Config) + c.AppName = config.GetEnv("APP_NAME", defAppName) + c.AppDomain = config.GetEnv("APP_DOMAIN", defAppDomain) + c.NetAddr = config.GetEnv("SERVER_ADDR", defNetAddr) + c.Port, _ = strconv.Atoi(c.NetAddr[1:]) + c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) + c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) + c.EventBusExchange = ebEventsExchange + + logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) + logger := fluentd.NewLogger(c.AppName, logHost, logPort) + defer logger.Close() + + // db conn + dbConn, err := database.Connect(c.DbURL) + if err != nil { // fixme: add wait-for-db... + logger.Log("Failed to connect to Database server: %v\n", err) + os.Exit(1) + } + defer dbConn.Close() + + // eventbus conn + ebConn, ebCh, err := amqp.Open(c.EventBusURL) + if err != nil { + logger.Log("Failed to connect to EventBus server: %v\n", err) + os.Exit(1) + } + defer ebCh.Close() + defer amqp.Close(ebConn) + + err = amqp.NewExchange(ebCh, c.EventBusExchange) + if err != nil { + logger.Log("Failed to declare EventBus exchange: %v\n", err) + os.Exit(1) + } + + // start server + srv := server.NewServer(c, logger, dbConn, ebCh) + srv.StartWithGracefulShutdown() +} diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go new file mode 100644 index 0000000..e14544c --- /dev/null +++ b/src/cmd/worker/main.go @@ -0,0 +1,130 @@ +package main + +import ( + "fmt" + "log" + "os" + "strings" + + "git.pbiernat.dev/egommerce/order-service/internal/app/config" + "git.pbiernat.dev/egommerce/order-service/internal/app/database" + "git.pbiernat.dev/egommerce/order-service/internal/app/server" + "git.pbiernat.dev/egommerce/order-service/pkg/amqp" + "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" + "github.com/google/uuid" +) + +const ( + defAppName = "order-worker" + defLoggerAddr = "api-logger:24224" + defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" + defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" + defEventBusURL = "amqp://guest:guest@api-eventbus:5672" + ebEventsExchange = "api-events" + ebEventsQueue = "order-worker" +) + +func main() { + if config.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + } + + id := uuid.New().String()[24:] + c := new(server.Config) + c.AppName = config.GetEnv("APP_NAME", defAppName) + "#:" + id + c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) + c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) + c.EventBusExchange = ebEventsExchange + c.EventBusQueue = ebEventsQueue + // c.EventBusQueue = fmt.Sprintf("%s-%s", ebEventsQueue, id) + + logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) + logger := fluentd.NewLogger(c.AppName, logHost, logPort) + defer logger.Close() + + // db conn + dbConn, err := database.Connect(c.DbURL) + if err != nil { // fixme: add wait-for-db... + logger.Log("Failed to connect to Database server: %v\n", err) + os.Exit(1) + } + defer dbConn.Close() + + // eventbus conn + ebConn, ebCh, err := amqp.Open(c.EventBusURL) + if err != nil { + logger.Log("Failed to connect to EventBus server: %v\n", err) + os.Exit(1) + } + defer ebCh.Close() + defer amqp.Close(ebConn) + + err = amqp.NewExchange(ebCh, c.EventBusExchange) + if err != nil { + logger.Log("Failed to declare EventBus exchange: %v\n", err) + os.Exit(1) + } + + // create and bind queues + _, err = ebCh.QueueDeclare( + c.EventBusQueue, // name + false, // durable + false, // delete when unused + false, // exclusive + false, // no-wait + nil, // arguments + ) + if err != nil { + logger.Log("Failed to declare EventBus queue: %v\n", err) + os.Exit(1) + } + + err = amqp.BindQueueToExchange(ebCh, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") + if err != nil { + logger.Log("Failed to prepare EventBus queue: %v\n", err) + os.Exit(1) + } + + msgs, err := ebCh.Consume( + c.EventBusQueue, // queue + "", // consumer + false, // auto-ack + false, // exclusive + false, // no-local + false, // no-wait + nil, // args + ) + if err != nil { + logger.Log("Failed to register a consumer: %s", err) + os.Exit(1) + } + + var forever chan struct{} + go func() { + for d := range msgs { + msg, err := amqp.Deserialize(d.Body) + if err != nil { + logger.Log("json error:", err) + d.Reject(false) // FIXME: how to handle erros in queue...???? + continue + } + + event := fmt.Sprintf("%s", msg["event"]) + data := (msg["data"]).(map[string]interface{}) + logger.Log("Message<%s>: %s\n", event, data) + + switch true { + case strings.Contains(event, amqp.EVENT_BASKET_CHECKOUT): + // create new order based on basket + logger.Log("Event: %s", amqp.EVENT_BASKET_CHECKOUT) + } + + logger.Log("ACK: %s", event) + d.Ack(false) + } + }() + + logger.Log("Waiting for messages...") + <-forever +} diff --git a/src/go.mod b/src/go.mod new file mode 100644 index 0000000..c2b9cee --- /dev/null +++ b/src/go.mod @@ -0,0 +1,49 @@ +module git.pbiernat.dev/egommerce/order-service + +go 1.18 + +require ( + github.com/fluent/fluent-logger-golang v1.9.0 + github.com/gofiber/fiber/v2 v2.40.1 + github.com/google/uuid v1.3.0 + github.com/hashicorp/consul/api v1.17.0 + github.com/jackc/pgx/v4 v4.17.2 + github.com/joho/godotenv v1.4.0 + github.com/streadway/amqp v1.0.0 +) + +require ( + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/fatih/color v1.9.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/hashicorp/go-hclog v0.12.0 // indirect + github.com/hashicorp/go-immutable-radix v1.0.0 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/serf v0.10.1 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.13.0 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgtype v1.12.0 // indirect + github.com/jackc/puddle v1.3.0 // indirect + github.com/klauspost/compress v1.15.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/philhofer/fwd v1.1.1 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/tinylib/msgp v1.1.6 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.41.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/text v0.3.7 // indirect +) diff --git a/src/go.sum b/src/go.sum new file mode 100644 index 0000000..d2ebb07 --- /dev/null +++ b/src/go.sum @@ -0,0 +1,333 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= +github.com/fluent/fluent-logger-golang v1.9.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= +github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/consul/api v1.17.0 h1:aqytbw31uCPNn37ST+717IyGod+P1eTgSGu3yjRo4bs= +github.com/hashicorp/consul/api v1.17.0/go.mod h1:ZNwemOPAdgtV4cCx9fqxNmw+PI3vliW6gYin2WD+F2g= +github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= +github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= +github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= +github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= +github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= +github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= +github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= +github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY= +github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/src/internal/app/config/env.go b/src/internal/app/config/env.go new file mode 100644 index 0000000..9dbe349 --- /dev/null +++ b/src/internal/app/config/env.go @@ -0,0 +1,22 @@ +package config + +import ( + "os" + + "github.com/joho/godotenv" +) + +var ErrLoadingEnvs error + +func init() { + ErrLoadingEnvs = godotenv.Load() +} + +func GetEnv(name string, defVal string) string { // FIXME defVal and return types + env := os.Getenv(name) + if env == "" { + return defVal + } + + return env +} diff --git a/src/internal/app/database/connect.go b/src/internal/app/database/connect.go new file mode 100644 index 0000000..b44cfdd --- /dev/null +++ b/src/internal/app/database/connect.go @@ -0,0 +1,16 @@ +package database + +import ( + "context" + + "github.com/jackc/pgx/v4/pgxpool" +) + +func Connect(connStr string) (*pgxpool.Pool, error) { + conn, err := pgxpool.Connect(context.Background(), connStr) + if err != nil { + return nil, err + } + + return conn, nil +} diff --git a/src/internal/app/definition/error.go b/src/internal/app/definition/error.go new file mode 100644 index 0000000..28f7dbf --- /dev/null +++ b/src/internal/app/definition/error.go @@ -0,0 +1,9 @@ +package definition + +type ErrorResponse struct { + Error string `json:"error"` +} + +func Error(err string) *ErrorResponse { + return &ErrorResponse{err} +} diff --git a/src/internal/app/definition/health.go b/src/internal/app/definition/health.go new file mode 100644 index 0000000..6920fca --- /dev/null +++ b/src/internal/app/definition/health.go @@ -0,0 +1,5 @@ +package definition + +type HealthResponse struct { + Status string `json:"status,omitempty"` +} diff --git a/src/internal/app/definition/order_status.go b/src/internal/app/definition/order_status.go new file mode 100644 index 0000000..3345ffb --- /dev/null +++ b/src/internal/app/definition/order_status.go @@ -0,0 +1,8 @@ +package definition + +type UpdateOrderStatusRequest struct { + Status string `json:"status"` +} + +type UpdateOrderStatusResponse struct { +} diff --git a/src/internal/app/event/email.go b/src/internal/app/event/email.go new file mode 100644 index 0000000..76128aa --- /dev/null +++ b/src/internal/app/event/email.go @@ -0,0 +1,7 @@ +package event + +type StatusUpdateEvent struct { + *Event + OrderID string `json:"order_id"` + Status string `json:"status"` +} diff --git a/src/internal/app/event/event.go b/src/internal/app/event/event.go new file mode 100644 index 0000000..3dd7a42 --- /dev/null +++ b/src/internal/app/event/event.go @@ -0,0 +1,12 @@ +package event + +type Event struct { + RequestID string `json:"request_id"` +} + +func NewEvent(reqID string) *Event { + em := new(Event) + em.RequestID = reqID + + return em +} diff --git a/src/internal/app/server/config.go b/src/internal/app/server/config.go new file mode 100644 index 0000000..89e4ea1 --- /dev/null +++ b/src/internal/app/server/config.go @@ -0,0 +1,15 @@ +package server + +type Config struct { + AppName string + AppDomain string + NetAddr string + // Host string + Port int + LoggerAddr string + DbURL string + MongoDbUrl string + EventBusURL string + EventBusExchange string + EventBusQueue string +} diff --git a/src/internal/app/server/health_handler.go b/src/internal/app/server/health_handler.go new file mode 100644 index 0000000..9178d24 --- /dev/null +++ b/src/internal/app/server/health_handler.go @@ -0,0 +1,13 @@ +package server + +import ( + "github.com/gofiber/fiber/v2" + + def "git.pbiernat.dev/egommerce/order-service/internal/app/definition" +) + +func (s *Server) HealthHandler(c *fiber.Ctx) error { + return c.JSON(&def.HealthResponse{ + Status: "OK", + }) +} diff --git a/src/internal/app/server/order_handler.go b/src/internal/app/server/order_handler.go new file mode 100644 index 0000000..3493b88 --- /dev/null +++ b/src/internal/app/server/order_handler.go @@ -0,0 +1,30 @@ +package server + +import ( + "net/http" + + "github.com/gofiber/fiber/v2" + + def "git.pbiernat.dev/egommerce/order-service/internal/app/definition" + "git.pbiernat.dev/egommerce/order-service/internal/app/service" +) + +func (s *Server) UpdateOrderStatusHandler(c *fiber.Ctx) error { + reqID, _ := s.GetRequestID(c) + data := new(def.UpdateOrderStatusRequest) + if err := c.BodyParser(data); err != nil { + return err + } + + // check if order exists in DB service... + orderId := c.Params("orderId") + var err error + if orderId == "" || err != nil { + return c.SendStatus(http.StatusBadRequest) + } + + order := service.NewOrderService(s.ebCh, s.log) + order.UpdateOrderStatus(reqID, orderId, data.Status) + + return c.SendStatus(http.StatusNoContent) +} diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go new file mode 100644 index 0000000..b9f01fb --- /dev/null +++ b/src/internal/app/server/router.go @@ -0,0 +1,31 @@ +package server + +import ( + "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" + "github.com/gofiber/fiber/v2" +) + +func SetupRoutes(s *Server) { + api := s.App.Group("/api") + v1 := api.Group("/v1") + order := v1.Group("/order") + order.Put("/:orderId/status", s.UpdateOrderStatusHandler) + + s.App.Get("/health", s.HealthHandler) +} + +func SetupMiddlewares(s *Server) { + s.App.Use(LoggingMiddleware(s.log)) +} + +// Middlewares +func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { + return func(c *fiber.Ctx) error { + log.Log("Request: %s, remote: %s, via: %s", + c.Request().URI().String(), + c.Context().RemoteIP().String(), + string(c.Context().UserAgent())) + + return c.Next() + } +} diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go new file mode 100644 index 0000000..f214934 --- /dev/null +++ b/src/internal/app/server/server.go @@ -0,0 +1,101 @@ +package server + +import ( + "os" + "os/signal" + "time" + + "github.com/gofiber/fiber/v2" + "github.com/jackc/pgx/v4/pgxpool" + "github.com/streadway/amqp" + + discovery "git.pbiernat.dev/egommerce/order-service/pkg/consul" + "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" +) + +type Server struct { + *fiber.App + log *fluentd.Logger + db *pgxpool.Pool + ebCh *amqp.Channel + name string + addr string +} + +type RequestID struct { + RequestID string `reqHeader:"x-request-id"` +} + +func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amqp.Channel) *Server { + discovery, err := discovery.NewService(conf.AppName, conf.AppDomain, conf.Port) + if err != nil { + logger.Log("Error connecting to api-registry: %v", err) + } + + logger.Log("Registering service with name: %s, address: %s", discovery.Name, discovery.Address) + err = discovery.Register() + if err != nil { + logger.Log(err.Error()) + } + + cnf := fiber.Config{ + AppName: conf.AppName, + ServerHeader: conf.AppDomain, + ReadTimeout: time.Millisecond * 50, + WriteTimeout: time.Millisecond * 50, + IdleTimeout: time.Millisecond * 50, + } + s := &Server{ + fiber.New(cnf), + logger, + db, + ebCh, + conf.AppName, + conf.NetAddr, + } + + SetupMiddlewares(s) + SetupRoutes(s) + + return s +} + +func (s *Server) Start() { + err := s.Listen(s.addr) + s.log.Log("Starting error: %v", err) +} + +func (s *Server) StartWithGracefulShutdown() { + idle := make(chan struct{}) + + go func() { + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt) + <-sigint + + if err := s.Shutdown(); err != nil { + s.log.Log("Server is not shutting down! Reason: %v", err) + } + + s.log.Log("Servier is going down...") + // remove info from registry and close all connection here... + + close(idle) + }() + + if err := s.Listen(s.addr); err != nil { + s.log.Log("Server is not running! Reason: %v", err) + } + + <-idle +} + +func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { + var hdr = new(RequestID) + if err := c.ReqHeaderParser(hdr); err != nil { + return "", err + } + + return hdr.RequestID, nil + +} diff --git a/src/internal/app/service/order.go b/src/internal/app/service/order.go new file mode 100644 index 0000000..61d7cc8 --- /dev/null +++ b/src/internal/app/service/order.go @@ -0,0 +1,27 @@ +package service + +import ( + "git.pbiernat.dev/egommerce/order-service/internal/app/event" + "git.pbiernat.dev/egommerce/order-service/pkg/amqp" + "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" + base "github.com/streadway/amqp" +) + +type OrderService struct { + ebCh *base.Channel + log *fluentd.Logger +} + +func NewOrderService(chn *base.Channel, log *fluentd.Logger) *OrderService { + return &OrderService{chn, log} +} + +func (s *OrderService) UpdateOrderStatus(reqID, orderID, status string) (string, error) { + s.log.Log("Update order#%s status to %s", orderID, status) + + msg := &event.StatusUpdateEvent{Event: event.NewEvent(reqID), OrderID: orderID, Status: status} + amqp.Publish(s.ebCh, "api-events", "order.email.statusUpdate", msg) + amqp.Publish(s.ebCh, "api-events", "order.warehouse.orderFinalized", msg) // test event... + + return orderID, nil +} diff --git a/src/pkg/amqp/connect.go b/src/pkg/amqp/connect.go new file mode 100644 index 0000000..9429823 --- /dev/null +++ b/src/pkg/amqp/connect.go @@ -0,0 +1,26 @@ +package amqp + +import ( + "log" + + "github.com/streadway/amqp" +) + +func Open(url string) (*amqp.Connection, *amqp.Channel, error) { + conn, err := amqp.Dial(url) + if err != nil { + return nil, nil, err + } + + ch, err := conn.Channel() + if err != nil { + log.Printf("Failed to open a channel: %v\n", err) + return nil, nil, err + } + + return conn, ch, nil +} + +func Close(conn *amqp.Connection) { + conn.Close() +} diff --git a/src/pkg/amqp/pubsub.go b/src/pkg/amqp/pubsub.go new file mode 100644 index 0000000..48448ed --- /dev/null +++ b/src/pkg/amqp/pubsub.go @@ -0,0 +1,88 @@ +package amqp + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + + "github.com/streadway/amqp" +) + +const ( + EVENT_BASKET_CHECKOUT = "event.BasketCheckoutEvent" +) + +type Message map[string]interface{} + +func Serialize(msg any /*Message*/) ([]byte, error) { + var b bytes.Buffer + encoder := json.NewEncoder(&b) + err := encoder.Encode(msg) + return b.Bytes(), err +} + +func Deserialize(b []byte) (Message, error) { + var msg Message + buf := bytes.NewBuffer(b) + decoder := json.NewDecoder(buf) + err := decoder.Decode(&msg) + return msg, err +} + +func NewExchange(chn *amqp.Channel, name string) error { + err := chn.ExchangeDeclare( + name, + "direct", // type + true, // durable + false, // auto-deleted + false, // internal + false, // no-wait + nil, // arguments + ) // FIXME extend arguments when needed... + + if err != nil { + return err + } + + return nil +} + +func Publish(chn *amqp.Channel, name, routingKey string, msg any) error { + // var jsonData []byte + jsonData, err := Serialize(msg) + if err != nil { + return err + } + + msgBody := fmt.Sprintf(`{"event":"%T","data":%s}`, msg, jsonData) // FIXME %T - simplify + chn.Publish( + name, // exchange name + routingKey, // routing key + false, // mandatory + false, // immediate + amqp.Publishing{ + ContentType: "application/json", + Body: []byte(msgBody), + }, + ) + + return nil +} + +func BindQueueToExchange(chn *amqp.Channel, queueName, exchName, routingKey string) error { + err := chn.QueueBind( + queueName, // queue name + routingKey, // routing key + exchName, // exchange name FIXME: use const: ebEventsExchange + false, + nil, + ) + if err != nil { + log.Printf("Failed to bind a queue: %s\n", queueName) + + return err + } + + return nil +} diff --git a/src/pkg/consul/discovery.go b/src/pkg/consul/discovery.go new file mode 100644 index 0000000..3a73054 --- /dev/null +++ b/src/pkg/consul/discovery.go @@ -0,0 +1,107 @@ +package consul + +import ( + "log" + "strconv" + "time" + + consul "github.com/hashicorp/consul/api" +) + +type Service struct { + Name string + Address string + Port int + TTL time.Duration + ConsulAgent *consul.Agent +} + +func NewService(appName, appDomain string, port int) (*Service, error) { + s := new(Service) + s.Name = appName + s.Address = appDomain + s.Port = port + s.TTL = time.Second * 15 + + client, err := consul.NewClient(newClientConfig()) + if err != nil { + return nil, err + } + s.ConsulAgent = client.Agent() + + // tags := s.GetTags() + + return s, nil +} + +func newClientConfig() *consul.Config { + conf := consul.DefaultConfig() + conf.Address = "api-registry:8500" // FIXME:consul server + + return conf +} + +func (s *Service) Register() error { + serviceDef := &consul.AgentServiceRegistration{ + Name: s.Name, + Address: s.Address, + Port: s.Port, + Tags: s.getTags(), + Check: &consul.AgentServiceCheck{ + TTL: s.TTL.String(), + }, + } + + if err := s.ConsulAgent.ServiceRegister(serviceDef); err != nil { + return err + } + go s.UpdateTTL(serviceDef /*service.Check*/) + + return nil +} + +func (s *Service) UpdateTTL(service *consul.AgentServiceRegistration /*check func() (bool, error)*/) { + ticker := time.NewTicker(s.TTL / 2) + for range ticker.C { + s.update(service /*check*/) + } +} + +func (s *Service) update(service *consul.AgentServiceRegistration /*check func() (bool, error)*/) { + // ok, err := check() + // if !ok { + // log.Printf("err=\"Check failed\" msg=\"%s\"", err.Error()) + // if err := s.ConsulAgent.FailTTL("service:"+s.Name, err.Error()); err != nil { + // log.Println(err) + // } + // } else { + // log.Println("Updating service info...") + if err := s.ConsulAgent.PassTTL("service:"+service.Name, ""); err != nil { + log.Println(err) + } + // } +} + +func (s *Service) getTags() []string { + name, addr, port := s.Name, s.Address, strconv.Itoa(s.Port) + + tags := []string{ + "traefik.enable=true", + "traefik.http.routers." + name + ".rule=Host(`" + addr + "`)", + "traefik.http.routers." + name + ".entryPoints=https", + "traefik.http.routers." + name + ".service=" + name, + "traefik.http.routers." + name + ".middlewares=compress,requestid", + "traefik.http.routers." + name + ".tls=true", + "traefik.http.services." + name + ".loadbalancer.server.scheme=http", + "traefik.http.services." + name + ".loadbalancer.server.port=" + port, + "traefik.http.services." + name + ".loadbalancer.passhostheader=false", + "traefik.http.middlewares.compress.compress=true", + "traefik.http.middlewares.requestid.plugin.requestid.headerName=X-Request-ID", + // "traefik.http.services." + name + ".loadbalancer.healthcheck.path=/health", + // "traefik.http.services." + name + ".loadbalancer.healthcheck.interval=10s", + // "traefik.tls.certificates.certfile=/certs/client.cert", + // "traefik.tls.certificates.keyfile=/certs/client.key", + } + + return tags +} diff --git a/src/pkg/fluentd/config.go b/src/pkg/fluentd/config.go new file mode 100644 index 0000000..48255d2 --- /dev/null +++ b/src/pkg/fluentd/config.go @@ -0,0 +1,14 @@ +package fluentd + +import ( + "strconv" + "strings" +) + +func ParseAddr(addr string) (string, int) { + p := strings.Split(addr, ":") + fHost := p[0] + fPort, _ := strconv.Atoi(p[1]) + + return fHost, fPort +} diff --git a/src/pkg/fluentd/logger.go b/src/pkg/fluentd/logger.go new file mode 100644 index 0000000..b398595 --- /dev/null +++ b/src/pkg/fluentd/logger.go @@ -0,0 +1,41 @@ +package fluentd + +import ( + "fmt" + "log" + + "github.com/fluent/fluent-logger-golang/fluent" +) + +type Logger struct { + fluent *fluent.Fluent + appName string +} + +func NewLogger(appName, fHost string, fPort int) *Logger { + config := fluent.Config{ + FluentHost: fHost, + FluentPort: fPort, + // WriteTimeout: -1, + } + fluent, err := fluent.New(config) + if err != nil { + log.Panicf("Error connecting to api-logger: %v", err) + } + + return &Logger{fluent, appName} +} + +func (l *Logger) Log(format string, v ...any) { + mapData := map[string]string{ + "message": fmt.Sprintf(format, v...), + } + err := l.fluent.Post(l.appName, mapData) + if err != nil { + log.Println("Error sending log: ", err) + } +} + +func (l *Logger) Close() error { + return l.fluent.Close() +} -- 2.39.5 From 642a94741f57352cc2eb44f8f5e230c146f75145 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Tue, 29 Nov 2022 23:33:43 +0100 Subject: [PATCH 02/18] CQ fix --- src/cmd/worker/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index e14544c..14b8e61 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -105,7 +105,7 @@ func main() { for d := range msgs { msg, err := amqp.Deserialize(d.Body) if err != nil { - logger.Log("json error:", err) + logger.Log("json error: %v\n", err) d.Reject(false) // FIXME: how to handle erros in queue...???? continue } -- 2.39.5 From f7802a1a519a4b02c853b22879ef2c7753115c09 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Wed, 30 Nov 2022 02:08:59 +0100 Subject: [PATCH 03/18] Refactored docker image builder script --- Dockerfile.builder | 14 ++++++++++++ Dockerfile.server | 30 ------------------------- Dockerfile.target | 22 ++++++++++++++++++ Dockerfile.worker | 30 ------------------------- deploy/image-build.sh | 52 ++++++++++++++++++++++++------------------- 5 files changed, 65 insertions(+), 83 deletions(-) create mode 100644 Dockerfile.builder delete mode 100644 Dockerfile.server create mode 100644 Dockerfile.target delete mode 100644 Dockerfile.worker diff --git a/Dockerfile.builder b/Dockerfile.builder new file mode 100644 index 0000000..9a0110d --- /dev/null +++ b/Dockerfile.builder @@ -0,0 +1,14 @@ +# Builder +FROM golang:alpine + +ARG BIN_OUTPUT=/go/bin +ARG GO_SERVER=cmd/server/main.go +ARG GO_WORKER=cmd/worker/main.go + +WORKDIR /go/src/app +COPY src ./ + +RUN go mod download && \ + export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ + go build -ldflags="-w -s" -o "$BIN_OUTPUT/server" $GO_SERVER && \ + go build -ldflags="-w -s" -o "$BIN_OUTPUT/worker" $GO_WORKER diff --git a/Dockerfile.server b/Dockerfile.server deleted file mode 100644 index e566008..0000000 --- a/Dockerfile.server +++ /dev/null @@ -1,30 +0,0 @@ -# Builder -FROM golang:alpine AS builder - -ARG BIN_OUTPUT=/go/bin/server -ARG GO_MAIN=cmd/server/main.go - -WORKDIR /go/src/app -COPY src ./ - -RUN go mod download && \ - export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ - go build -ldflags="-w -s" -o $BIN_OUTPUT $GO_MAIN - - -# Destination image - server -FROM gcr.io/distroless/base-debian10 - -ARG BIN_OUTPUT=/go/bin/server - -LABEL author="Piotr Biernat" -LABEL service="order-svc" -LABEL vendor="Egommerce" -LABEL version="1.0" - -WORKDIR / -COPY --from=builder $BIN_OUTPUT / -COPY .env.dist /.env - -EXPOSE 80 -ENTRYPOINT ["/server"] diff --git a/Dockerfile.target b/Dockerfile.target new file mode 100644 index 0000000..b1386ca --- /dev/null +++ b/Dockerfile.target @@ -0,0 +1,22 @@ +# Builder +ARG BUILDER_IMAGE="git.pbiernat.dev/egommerce/order-builder:latest" +FROM ${BUILDER_IMAGE} AS builder + +# Destination image - server +FROM gcr.io/distroless/base-debian10 + +ARG BIN_OUTPUT +ARG SVC_NAME +ARG SVC_VER + +LABEL author="Piotr Biernat" +LABEL vendor="egommerce" +LABEL service=${SVC_NAME} +LABEL version=${SVC_VER} + +WORKDIR / +COPY --from=builder $BIN_OUTPUT /app +COPY .env.dist /.env + +EXPOSE 80 +ENTRYPOINT ["/app"] diff --git a/Dockerfile.worker b/Dockerfile.worker deleted file mode 100644 index cadfd07..0000000 --- a/Dockerfile.worker +++ /dev/null @@ -1,30 +0,0 @@ -# Builder -FROM golang:alpine AS builder - -ARG BIN_OUTPUT=/go/bin/worker -ARG GO_WORKER=cmd/worker/main.go - -WORKDIR /go/src/app -COPY src ./ - -RUN go mod download && \ - export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ - go build -ldflags="-w -s" -o $BIN_OUTPUT $GO_WORKER - - -# Destination image - worker -FROM gcr.io/distroless/base-debian10 - -ARG BIN_OUTPUT=/go/bin/worker - -LABEL author="Piotr Biernat" -LABEL service="order-worker" -LABEL vendor="Egommerce" -LABEL version="1.0" - -WORKDIR / -COPY --from=builder $BIN_OUTPUT / -COPY .env.dist /.env - -EXPOSE 80 -ENTRYPOINT ["/worker"] diff --git a/deploy/image-build.sh b/deploy/image-build.sh index 4cba8d4..e10f663 100755 --- a/deploy/image-build.sh +++ b/deploy/image-build.sh @@ -1,31 +1,37 @@ #!/bin/sh # RUN IN REPO ROOT DIR !! -export IMAGE_BASE="git.pbiernat.dev/egommerce/order" -export SERVER_IMAGE="$IMAGE_BASE-svc" -export WORKER_IMAGE="$IMAGE_BASE-worker" +export IMAGE_PREFIX="git.pbiernat.dev/egommerce/order" +export BUILDER_IMAGE="$IMAGE_PREFIX-builder:tmp" +export SERVER_IMAGE="$IMAGE_PREFIX-svc" +export WORKER_IMAGE="$IMAGE_PREFIX-worker" TARGET=${1:-latest} -KIND=${2:-all} -if [ $KIND = "svc" ] || [ $KIND = "all" ]; then - echo "Building: $SERVER_IMAGE:$TARGET" - if [ $TARGET = "dev" ] - then - docker build --rm --no-cache -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.server . # >/dev/null 2>&1 - else - docker build --rm --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.server . >/dev/null 2>&1 - fi +docker build --no-cache -t "$BUILDER_IMAGE" -f Dockerfile.builder . >/dev/null && echo "Successfully tagged $BUILDER_IMAGE" + +echo "Building target $IMAGE_PREFIX images..." +if [ $TARGET = "latest" ] +then + # SERVER + docker build --build-arg SVC_NAME=basket-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ + --rm --build-arg BUILDER_IMAGE --cache-from "$SERVER_IMAGE:$TARGET" \ + -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.target . >/dev/null 2>&1 + + # WORKER + docker build --build-arg SVC_NAME=basket-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ + --rm --build-arg BUILDER_IMAGE --cache-from "$WORKER_IMAGE:$TARGET" \ + -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.target . >/dev/null 2>&1 +else + # SERVER + docker build --build-arg SVC_NAME=basket-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ + --rm --build-arg BUILDER_IMAGE --no-cache -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.target . \ + >/dev/null && echo "Successfully tagged $SERVER_IMAGE:$TARGET" + + # WORKER + docker build --build-arg SVC_NAME=basket-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ + --rm --build-arg BUILDER_IMAGE --no-cache -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.target . \ + >/dev/null && echo "Successfully tagged $WORKER_IMAGE:$TARGET" fi -if [ $KIND = "worker" ] || [ $KIND = "all" ]; then - echo "Building: $WORKER_IMAGE:$TARGET" - if [ $TARGET = "dev" ] - then - docker build --rm --no-cache -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.worker . # >/dev/null 2>&1 - else - docker build --rm --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.worker . >/dev/null 2>&1 - fi -fi -echo "Done." - +echo "Done." \ No newline at end of file -- 2.39.5 From 0cdaa00682946755c7317a4bb247488a0837bed2 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Thu, 1 Dec 2022 06:22:54 +0100 Subject: [PATCH 04/18] vendor support and image build optimalization --- Dockerfile.builder | 3 +- deploy/image-build.sh | 32 +++++---- src/cmd/server/main.go | 4 +- src/cmd/worker/main.go | 4 +- src/go.mod | 19 +++--- src/go.sum | 90 +++++++++++++++++++++++++ src/internal/app/server/router.go | 2 +- src/internal/app/server/server.go | 4 +- src/internal/app/service/order.go | 4 +- src/pkg/amqp/connect.go | 26 -------- src/pkg/amqp/pubsub.go | 88 ------------------------ src/pkg/consul/discovery.go | 107 ------------------------------ src/pkg/fluentd/config.go | 14 ---- src/pkg/fluentd/logger.go | 41 ------------ 14 files changed, 129 insertions(+), 309 deletions(-) delete mode 100644 src/pkg/amqp/connect.go delete mode 100644 src/pkg/amqp/pubsub.go delete mode 100644 src/pkg/consul/discovery.go delete mode 100644 src/pkg/fluentd/config.go delete mode 100644 src/pkg/fluentd/logger.go diff --git a/Dockerfile.builder b/Dockerfile.builder index 9a0110d..779d27f 100644 --- a/Dockerfile.builder +++ b/Dockerfile.builder @@ -8,7 +8,6 @@ ARG GO_WORKER=cmd/worker/main.go WORKDIR /go/src/app COPY src ./ -RUN go mod download && \ - export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ +RUN export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ go build -ldflags="-w -s" -o "$BIN_OUTPUT/server" $GO_SERVER && \ go build -ldflags="-w -s" -o "$BIN_OUTPUT/worker" $GO_WORKER diff --git a/deploy/image-build.sh b/deploy/image-build.sh index e10f663..8a65594 100755 --- a/deploy/image-build.sh +++ b/deploy/image-build.sh @@ -8,30 +8,34 @@ export WORKER_IMAGE="$IMAGE_PREFIX-worker" TARGET=${1:-latest} -docker build --no-cache -t "$BUILDER_IMAGE" -f Dockerfile.builder . >/dev/null && echo "Successfully tagged $BUILDER_IMAGE" +[ ! -d \"src/vendor\" ] && sh -c "cd src; go mod vendor" + +export DOCKER_BUILDKIT=1 + +docker build -t "$BUILDER_IMAGE" -f Dockerfile.builder . >/dev/null 2>&1 && echo "Successfully tagged $BUILDER_IMAGE" echo "Building target $IMAGE_PREFIX images..." if [ $TARGET = "latest" ] then # SERVER - docker build --build-arg SVC_NAME=basket-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ - --rm --build-arg BUILDER_IMAGE --cache-from "$SERVER_IMAGE:$TARGET" \ - -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.target . >/dev/null 2>&1 + docker build --build-arg SVC_NAME=catalog-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ + --rm --build-arg BUILDER_IMAGE --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & # WORKER - docker build --build-arg SVC_NAME=basket-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ - --rm --build-arg BUILDER_IMAGE --cache-from "$WORKER_IMAGE:$TARGET" \ - -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.target . >/dev/null 2>&1 + docker build --build-arg SVC_NAME=catalog-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ + --rm --build-arg BUILDER_IMAGE --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" else # SERVER - docker build --build-arg SVC_NAME=basket-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ - --rm --build-arg BUILDER_IMAGE --no-cache -t "$SERVER_IMAGE:$TARGET" -f Dockerfile.target . \ - >/dev/null && echo "Successfully tagged $SERVER_IMAGE:$TARGET" + docker build --build-arg SVC_NAME=catalog-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ + --rm --build-arg BUILDER_IMAGE --no-cache -t "$SERVER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & # WORKER - docker build --build-arg SVC_NAME=basket-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ - --rm --build-arg BUILDER_IMAGE --no-cache -t "$WORKER_IMAGE:$TARGET" -f Dockerfile.target . \ - >/dev/null && echo "Successfully tagged $WORKER_IMAGE:$TARGET" + docker build --build-arg SVC_NAME=catalog-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ + --rm --build-arg BUILDER_IMAGE --no-cache -t "$WORKER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" fi -echo "Done." \ No newline at end of file +echo "Done." diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index 51fa063..e4dd673 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -5,11 +5,11 @@ import ( "os" "strconv" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/config" "git.pbiernat.dev/egommerce/order-service/internal/app/database" "git.pbiernat.dev/egommerce/order-service/internal/app/server" - "git.pbiernat.dev/egommerce/order-service/pkg/amqp" - "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" ) const ( diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index 14b8e61..8f12daf 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -6,11 +6,11 @@ import ( "os" "strings" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/config" "git.pbiernat.dev/egommerce/order-service/internal/app/database" "git.pbiernat.dev/egommerce/order-service/internal/app/server" - "git.pbiernat.dev/egommerce/order-service/pkg/amqp" - "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" "github.com/google/uuid" ) diff --git a/src/go.mod b/src/go.mod index c2b9cee..fae1d84 100644 --- a/src/go.mod +++ b/src/go.mod @@ -6,20 +6,23 @@ require ( github.com/fluent/fluent-logger-golang v1.9.0 github.com/gofiber/fiber/v2 v2.40.1 github.com/google/uuid v1.3.0 - github.com/hashicorp/consul/api v1.17.0 + github.com/hashicorp/consul/api v1.18.0 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 github.com/streadway/amqp v1.0.0 ) require ( + git.pbiernat.dev/egommerce/go-api-pkg/consul v0.0.0-20221201033742-97afd0d96662 // indirect + git.pbiernat.dev/egommerce/go-api-pkg/fluentd v0.0.0-20221201033742-97afd0d96662 // indirect + git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq v0.0.0-20221201033742-97afd0d96662 // indirect github.com/andybalholm/brotli v1.0.4 // indirect - github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect - github.com/fatih/color v1.9.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.1 // indirect - github.com/hashicorp/go-hclog v0.12.0 // indirect - github.com/hashicorp/go-immutable-radix v1.0.0 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.3.1 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect @@ -36,7 +39,7 @@ require ( github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/philhofer/fwd v1.1.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/tinylib/msgp v1.1.6 // indirect @@ -44,6 +47,6 @@ require ( github.com/valyala/fasthttp v1.41.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.3.7 // indirect ) diff --git a/src/go.sum b/src/go.sum index d2ebb07..244c108 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,15 +1,34 @@ +git.pbiernat.dev/egommerce/go-api-pkg/consul v0.0.0-20221201033742-97afd0d96662 h1:Z6D9KDaHS/TL2jcY10M0UxqyGcaXn7jK7P6ja8+ytkg= +git.pbiernat.dev/egommerce/go-api-pkg/consul v0.0.0-20221201033742-97afd0d96662/go.mod h1:lDctRzmIVtFNCPrXAOAOQJvi52KjfOqhgTftQ6gTE7U= +git.pbiernat.dev/egommerce/go-api-pkg/fluentd v0.0.0-20221201033742-97afd0d96662 h1:AG5rRYaXQFyL9XtZLkKfBQGyOBbGRQAqrgtLL6KoQTo= +git.pbiernat.dev/egommerce/go-api-pkg/fluentd v0.0.0-20221201033742-97afd0d96662/go.mod h1:/7GWyTxCHuk7y1aQtxJkTMuXNG6utr8APWjvOp51H7A= +git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq v0.0.0-20221201033742-97afd0d96662 h1:2skXunz8yjmYK0H5VOsXRhuyFrPo86PpL4b8heBei3I= +git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq v0.0.0-20221201033742-97afd0d96662/go.mod h1:gJQ6go/IGbrDkIftZO8cubLCu8Rbt5SWCh4EZMcdsW8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -22,39 +41,62 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= github.com/fluent/fluent-logger-golang v1.9.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/consul/api v1.17.0 h1:aqytbw31uCPNn37ST+717IyGod+P1eTgSGu3yjRo4bs= github.com/hashicorp/consul/api v1.17.0/go.mod h1:ZNwemOPAdgtV4cCx9fqxNmw+PI3vliW6gYin2WD+F2g= +github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= +github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= +github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -126,11 +168,15 @@ github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -149,6 +195,8 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -158,10 +206,12 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -173,10 +223,19 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -184,6 +243,17 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -198,6 +268,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= @@ -213,10 +284,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY= @@ -236,6 +309,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -253,8 +327,10 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -265,11 +341,15 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -281,6 +361,7 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -288,10 +369,15 @@ golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -320,12 +406,16 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go index b9f01fb..5ae3a37 100644 --- a/src/internal/app/server/router.go +++ b/src/internal/app/server/router.go @@ -1,7 +1,7 @@ package server import ( - "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" "github.com/gofiber/fiber/v2" ) diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go index f214934..5af8f0f 100644 --- a/src/internal/app/server/server.go +++ b/src/internal/app/server/server.go @@ -9,8 +9,8 @@ import ( "github.com/jackc/pgx/v4/pgxpool" "github.com/streadway/amqp" - discovery "git.pbiernat.dev/egommerce/order-service/pkg/consul" - "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" + discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" ) type Server struct { diff --git a/src/internal/app/service/order.go b/src/internal/app/service/order.go index 61d7cc8..99a02ed 100644 --- a/src/internal/app/service/order.go +++ b/src/internal/app/service/order.go @@ -1,9 +1,9 @@ package service import ( + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/event" - "git.pbiernat.dev/egommerce/order-service/pkg/amqp" - "git.pbiernat.dev/egommerce/order-service/pkg/fluentd" base "github.com/streadway/amqp" ) diff --git a/src/pkg/amqp/connect.go b/src/pkg/amqp/connect.go deleted file mode 100644 index 9429823..0000000 --- a/src/pkg/amqp/connect.go +++ /dev/null @@ -1,26 +0,0 @@ -package amqp - -import ( - "log" - - "github.com/streadway/amqp" -) - -func Open(url string) (*amqp.Connection, *amqp.Channel, error) { - conn, err := amqp.Dial(url) - if err != nil { - return nil, nil, err - } - - ch, err := conn.Channel() - if err != nil { - log.Printf("Failed to open a channel: %v\n", err) - return nil, nil, err - } - - return conn, ch, nil -} - -func Close(conn *amqp.Connection) { - conn.Close() -} diff --git a/src/pkg/amqp/pubsub.go b/src/pkg/amqp/pubsub.go deleted file mode 100644 index 48448ed..0000000 --- a/src/pkg/amqp/pubsub.go +++ /dev/null @@ -1,88 +0,0 @@ -package amqp - -import ( - "bytes" - "encoding/json" - "fmt" - "log" - - "github.com/streadway/amqp" -) - -const ( - EVENT_BASKET_CHECKOUT = "event.BasketCheckoutEvent" -) - -type Message map[string]interface{} - -func Serialize(msg any /*Message*/) ([]byte, error) { - var b bytes.Buffer - encoder := json.NewEncoder(&b) - err := encoder.Encode(msg) - return b.Bytes(), err -} - -func Deserialize(b []byte) (Message, error) { - var msg Message - buf := bytes.NewBuffer(b) - decoder := json.NewDecoder(buf) - err := decoder.Decode(&msg) - return msg, err -} - -func NewExchange(chn *amqp.Channel, name string) error { - err := chn.ExchangeDeclare( - name, - "direct", // type - true, // durable - false, // auto-deleted - false, // internal - false, // no-wait - nil, // arguments - ) // FIXME extend arguments when needed... - - if err != nil { - return err - } - - return nil -} - -func Publish(chn *amqp.Channel, name, routingKey string, msg any) error { - // var jsonData []byte - jsonData, err := Serialize(msg) - if err != nil { - return err - } - - msgBody := fmt.Sprintf(`{"event":"%T","data":%s}`, msg, jsonData) // FIXME %T - simplify - chn.Publish( - name, // exchange name - routingKey, // routing key - false, // mandatory - false, // immediate - amqp.Publishing{ - ContentType: "application/json", - Body: []byte(msgBody), - }, - ) - - return nil -} - -func BindQueueToExchange(chn *amqp.Channel, queueName, exchName, routingKey string) error { - err := chn.QueueBind( - queueName, // queue name - routingKey, // routing key - exchName, // exchange name FIXME: use const: ebEventsExchange - false, - nil, - ) - if err != nil { - log.Printf("Failed to bind a queue: %s\n", queueName) - - return err - } - - return nil -} diff --git a/src/pkg/consul/discovery.go b/src/pkg/consul/discovery.go deleted file mode 100644 index 3a73054..0000000 --- a/src/pkg/consul/discovery.go +++ /dev/null @@ -1,107 +0,0 @@ -package consul - -import ( - "log" - "strconv" - "time" - - consul "github.com/hashicorp/consul/api" -) - -type Service struct { - Name string - Address string - Port int - TTL time.Duration - ConsulAgent *consul.Agent -} - -func NewService(appName, appDomain string, port int) (*Service, error) { - s := new(Service) - s.Name = appName - s.Address = appDomain - s.Port = port - s.TTL = time.Second * 15 - - client, err := consul.NewClient(newClientConfig()) - if err != nil { - return nil, err - } - s.ConsulAgent = client.Agent() - - // tags := s.GetTags() - - return s, nil -} - -func newClientConfig() *consul.Config { - conf := consul.DefaultConfig() - conf.Address = "api-registry:8500" // FIXME:consul server - - return conf -} - -func (s *Service) Register() error { - serviceDef := &consul.AgentServiceRegistration{ - Name: s.Name, - Address: s.Address, - Port: s.Port, - Tags: s.getTags(), - Check: &consul.AgentServiceCheck{ - TTL: s.TTL.String(), - }, - } - - if err := s.ConsulAgent.ServiceRegister(serviceDef); err != nil { - return err - } - go s.UpdateTTL(serviceDef /*service.Check*/) - - return nil -} - -func (s *Service) UpdateTTL(service *consul.AgentServiceRegistration /*check func() (bool, error)*/) { - ticker := time.NewTicker(s.TTL / 2) - for range ticker.C { - s.update(service /*check*/) - } -} - -func (s *Service) update(service *consul.AgentServiceRegistration /*check func() (bool, error)*/) { - // ok, err := check() - // if !ok { - // log.Printf("err=\"Check failed\" msg=\"%s\"", err.Error()) - // if err := s.ConsulAgent.FailTTL("service:"+s.Name, err.Error()); err != nil { - // log.Println(err) - // } - // } else { - // log.Println("Updating service info...") - if err := s.ConsulAgent.PassTTL("service:"+service.Name, ""); err != nil { - log.Println(err) - } - // } -} - -func (s *Service) getTags() []string { - name, addr, port := s.Name, s.Address, strconv.Itoa(s.Port) - - tags := []string{ - "traefik.enable=true", - "traefik.http.routers." + name + ".rule=Host(`" + addr + "`)", - "traefik.http.routers." + name + ".entryPoints=https", - "traefik.http.routers." + name + ".service=" + name, - "traefik.http.routers." + name + ".middlewares=compress,requestid", - "traefik.http.routers." + name + ".tls=true", - "traefik.http.services." + name + ".loadbalancer.server.scheme=http", - "traefik.http.services." + name + ".loadbalancer.server.port=" + port, - "traefik.http.services." + name + ".loadbalancer.passhostheader=false", - "traefik.http.middlewares.compress.compress=true", - "traefik.http.middlewares.requestid.plugin.requestid.headerName=X-Request-ID", - // "traefik.http.services." + name + ".loadbalancer.healthcheck.path=/health", - // "traefik.http.services." + name + ".loadbalancer.healthcheck.interval=10s", - // "traefik.tls.certificates.certfile=/certs/client.cert", - // "traefik.tls.certificates.keyfile=/certs/client.key", - } - - return tags -} diff --git a/src/pkg/fluentd/config.go b/src/pkg/fluentd/config.go deleted file mode 100644 index 48255d2..0000000 --- a/src/pkg/fluentd/config.go +++ /dev/null @@ -1,14 +0,0 @@ -package fluentd - -import ( - "strconv" - "strings" -) - -func ParseAddr(addr string) (string, int) { - p := strings.Split(addr, ":") - fHost := p[0] - fPort, _ := strconv.Atoi(p[1]) - - return fHost, fPort -} diff --git a/src/pkg/fluentd/logger.go b/src/pkg/fluentd/logger.go deleted file mode 100644 index b398595..0000000 --- a/src/pkg/fluentd/logger.go +++ /dev/null @@ -1,41 +0,0 @@ -package fluentd - -import ( - "fmt" - "log" - - "github.com/fluent/fluent-logger-golang/fluent" -) - -type Logger struct { - fluent *fluent.Fluent - appName string -} - -func NewLogger(appName, fHost string, fPort int) *Logger { - config := fluent.Config{ - FluentHost: fHost, - FluentPort: fPort, - // WriteTimeout: -1, - } - fluent, err := fluent.New(config) - if err != nil { - log.Panicf("Error connecting to api-logger: %v", err) - } - - return &Logger{fluent, appName} -} - -func (l *Logger) Log(format string, v ...any) { - mapData := map[string]string{ - "message": fmt.Sprintf(format, v...), - } - err := l.fluent.Post(l.appName, mapData) - if err != nil { - log.Println("Error sending log: ", err) - } -} - -func (l *Logger) Close() error { - return l.fluent.Close() -} -- 2.39.5 From 896321e94546721a5f1062c8352a84a636746e8f Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 2 Dec 2022 20:12:08 +0100 Subject: [PATCH 05/18] Refactor. Consul TTl fix, gracefull shutdown --- Dockerfile.target | 11 ++++--- deploy/image-build.sh | 10 +++--- src/cmd/server/main.go | 12 +++++-- src/cmd/worker/main.go | 46 +++++++++++++++++--------- src/go.mod | 10 ++---- src/go.sum | 30 +++++++---------- src/internal/app/event/order.go | 10 ++++++ src/internal/app/log.go | 20 ++++++++++++ src/internal/app/server/config.go | 15 ++++++--- src/internal/app/server/server.go | 54 ++++++++++++++++++------------- 10 files changed, 138 insertions(+), 80 deletions(-) create mode 100644 src/internal/app/event/order.go create mode 100644 src/internal/app/log.go diff --git a/Dockerfile.target b/Dockerfile.target index b1386ca..3c233b4 100644 --- a/Dockerfile.target +++ b/Dockerfile.target @@ -3,16 +3,17 @@ ARG BUILDER_IMAGE="git.pbiernat.dev/egommerce/order-builder:latest" FROM ${BUILDER_IMAGE} AS builder # Destination image - server -FROM gcr.io/distroless/base-debian10 +# FROM gcr.io/distroless/base-debian10 +FROM alpine:3.17 ARG BIN_OUTPUT ARG SVC_NAME ARG SVC_VER -LABEL author="Piotr Biernat" -LABEL vendor="egommerce" -LABEL service=${SVC_NAME} -LABEL version=${SVC_VER} +LABEL dev.egommerce.image.author="Piotr Biernat" +LABEL dev.egommerce.image.service="api-eventubus" +LABEL dev.egommerce.image.service=${SVC_NAME} +LABEL dev.egommerce.image.version=${SVC_VER} WORKDIR / COPY --from=builder $BIN_OUTPUT /app diff --git a/deploy/image-build.sh b/deploy/image-build.sh index 8a65594..243f419 100755 --- a/deploy/image-build.sh +++ b/deploy/image-build.sh @@ -12,28 +12,28 @@ TARGET=${1:-latest} export DOCKER_BUILDKIT=1 -docker build -t "$BUILDER_IMAGE" -f Dockerfile.builder . >/dev/null 2>&1 && echo "Successfully tagged $BUILDER_IMAGE" +docker build -t "$BUILDER_IMAGE" -f Dockerfile.builder . && echo "Successfully tagged $BUILDER_IMAGE" echo "Building target $IMAGE_PREFIX images..." if [ $TARGET = "latest" ] then # SERVER - docker build --build-arg SVC_NAME=catalog-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ + docker build --build-arg SVC_NAME=order-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ --rm --build-arg BUILDER_IMAGE --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" \ -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & # WORKER - docker build --build-arg SVC_NAME=catalog-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ + docker build --build-arg SVC_NAME=order-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ --rm --build-arg BUILDER_IMAGE --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" \ -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" else # SERVER - docker build --build-arg SVC_NAME=catalog-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ + docker build --build-arg SVC_NAME=order-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ --rm --build-arg BUILDER_IMAGE --no-cache -t "$SERVER_IMAGE:$TARGET" \ -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & # WORKER - docker build --build-arg SVC_NAME=catalog-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ + docker build --build-arg SVC_NAME=order-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ --rm --build-arg BUILDER_IMAGE --no-cache -t "$WORKER_IMAGE:$TARGET" \ -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" fi diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index e4dd673..181ed88 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -17,6 +17,7 @@ const ( defAppDomain = "order-svc" defNetAddr = ":80" defLoggerAddr = "api-logger:24224" + defRegistryAddr = "api-registry:8500" defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" defEventBusURL = "amqp://guest:guest@api-eventbus:5672" @@ -30,17 +31,19 @@ func main() { } c := new(server.Config) + c.AppID, _ = os.Hostname() c.AppName = config.GetEnv("APP_NAME", defAppName) c.AppDomain = config.GetEnv("APP_DOMAIN", defAppDomain) c.NetAddr = config.GetEnv("SERVER_ADDR", defNetAddr) c.Port, _ = strconv.Atoi(c.NetAddr[1:]) c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) c.EventBusExchange = ebEventsExchange logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) - logger := fluentd.NewLogger(c.AppName, logHost, logPort) + logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) defer logger.Close() // db conn @@ -68,5 +71,10 @@ func main() { // start server srv := server.NewServer(c, logger, dbConn, ebCh) - srv.StartWithGracefulShutdown() + + forever := make(chan struct{}) + srv.StartWithGracefulShutdown(forever) + <-forever + + // os.Exit(1) } diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index 8f12daf..2b4ccc8 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -4,19 +4,22 @@ import ( "fmt" "log" "os" + "os/signal" "strings" + "syscall" "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/config" "git.pbiernat.dev/egommerce/order-service/internal/app/database" + "git.pbiernat.dev/egommerce/order-service/internal/app/event" "git.pbiernat.dev/egommerce/order-service/internal/app/server" - "github.com/google/uuid" ) const ( defAppName = "order-worker" defLoggerAddr = "api-logger:24224" + defRegistryAddr = "api-registry:8500" defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" defEventBusURL = "amqp://guest:guest@api-eventbus:5672" @@ -29,18 +32,18 @@ func main() { log.Panicln("Error loading .env file", config.ErrLoadingEnvs) } - id := uuid.New().String()[24:] c := new(server.Config) - c.AppName = config.GetEnv("APP_NAME", defAppName) + "#:" + id + c.AppID, _ = os.Hostname() + c.AppName = config.GetEnv("APP_NAME", defAppName) c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) c.EventBusExchange = ebEventsExchange c.EventBusQueue = ebEventsQueue - // c.EventBusQueue = fmt.Sprintf("%s-%s", ebEventsQueue, id) logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) - logger := fluentd.NewLogger(c.AppName, logHost, logPort) + logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) defer logger.Close() // db conn @@ -80,12 +83,13 @@ func main() { os.Exit(1) } - err = amqp.BindQueueToExchange(ebCh, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") - if err != nil { - logger.Log("Failed to prepare EventBus queue: %v\n", err) - os.Exit(1) - } + amqp.BindQueueToExchange(ebCh, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") + // if err != nil { + // logger.Log("Failed to prepare EventBus queue: %v\n", err) + // os.Exit(1) + // } + // event consume msgs, err := ebCh.Consume( c.EventBusQueue, // queue "", // consumer @@ -100,7 +104,17 @@ func main() { os.Exit(1) } - var forever chan struct{} + forever := make(chan struct{}) + go func() { + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + <-sigint + + logger.Log("Worker %s stopped working...\n", c.GetAppFullName()) + + close(forever) + }() + go func() { for d := range msgs { msg, err := amqp.Deserialize(d.Body) @@ -110,17 +124,17 @@ func main() { continue } - event := fmt.Sprintf("%s", msg["event"]) + eName := fmt.Sprintf("%s", msg["event"]) data := (msg["data"]).(map[string]interface{}) - logger.Log("Message<%s>: %s\n", event, data) + logger.Log("Message<%s>: %s\n", eName, data) switch true { - case strings.Contains(event, amqp.EVENT_BASKET_CHECKOUT): + case strings.Contains(eName, event.EVENT_BASKET_CHECKOUT): // create new order based on basket - logger.Log("Event: %s", amqp.EVENT_BASKET_CHECKOUT) + logger.Log("Event: %s", event.EVENT_BASKET_CHECKOUT) } - logger.Log("ACK: %s", event) + logger.Log("ACK: %s", eName) d.Ack(false) } }() diff --git a/src/go.mod b/src/go.mod index fae1d84..f828404 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,23 +3,19 @@ module git.pbiernat.dev/egommerce/order-service go 1.18 require ( - github.com/fluent/fluent-logger-golang v1.9.0 + git.pbiernat.dev/egommerce/go-api-pkg v0.0.101 github.com/gofiber/fiber/v2 v2.40.1 - github.com/google/uuid v1.3.0 - github.com/hashicorp/consul/api v1.18.0 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 github.com/streadway/amqp v1.0.0 ) require ( - git.pbiernat.dev/egommerce/go-api-pkg/consul v0.0.0-20221201033742-97afd0d96662 // indirect - git.pbiernat.dev/egommerce/go-api-pkg/fluentd v0.0.0-20221201033742-97afd0d96662 // indirect - git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq v0.0.0-20221201033742-97afd0d96662 // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/fatih/color v1.13.0 // indirect + github.com/fluent/fluent-logger-golang v1.9.0 // indirect + github.com/hashicorp/consul/api v1.18.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.3.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect diff --git a/src/go.sum b/src/go.sum index 244c108..2bb5cb8 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,9 +1,13 @@ -git.pbiernat.dev/egommerce/go-api-pkg/consul v0.0.0-20221201033742-97afd0d96662 h1:Z6D9KDaHS/TL2jcY10M0UxqyGcaXn7jK7P6ja8+ytkg= -git.pbiernat.dev/egommerce/go-api-pkg/consul v0.0.0-20221201033742-97afd0d96662/go.mod h1:lDctRzmIVtFNCPrXAOAOQJvi52KjfOqhgTftQ6gTE7U= -git.pbiernat.dev/egommerce/go-api-pkg/fluentd v0.0.0-20221201033742-97afd0d96662 h1:AG5rRYaXQFyL9XtZLkKfBQGyOBbGRQAqrgtLL6KoQTo= -git.pbiernat.dev/egommerce/go-api-pkg/fluentd v0.0.0-20221201033742-97afd0d96662/go.mod h1:/7GWyTxCHuk7y1aQtxJkTMuXNG6utr8APWjvOp51H7A= -git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq v0.0.0-20221201033742-97afd0d96662 h1:2skXunz8yjmYK0H5VOsXRhuyFrPo86PpL4b8heBei3I= -git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq v0.0.0-20221201033742-97afd0d96662/go.mod h1:gJQ6go/IGbrDkIftZO8cubLCu8Rbt5SWCh4EZMcdsW8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.32 h1:ArB/n30m927WMAM4u51guH+qR0Lu4NGyYnYdi7OhlzY= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.32/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.33 h1:1tm+pvUeS6OZLvHmLM3BwFS0Ty/eA3jDRuB60OicosA= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.33/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.34 h1:UO1x6O+cyU7yYYbDCDyhhAypuf4QGIXcmWcBEEjLuYM= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.34/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.100 h1:jw4fiGbZTsfJXJpGV+HQiYeMGZ7DMRMoepjuIwY6FIU= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.100/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.101 h1:NZCFAAlC94+LcN1gjrENnWUHvpWgaNksyB2N4Fiy8C4= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.101/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -14,7 +18,6 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= @@ -25,7 +28,6 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= @@ -39,7 +41,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -68,10 +69,6 @@ github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/consul/api v1.17.0 h1:aqytbw31uCPNn37ST+717IyGod+P1eTgSGu3yjRo4bs= -github.com/hashicorp/consul/api v1.17.0/go.mod h1:ZNwemOPAdgtV4cCx9fqxNmw+PI3vliW6gYin2WD+F2g= github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= @@ -79,15 +76,12 @@ github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95e github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -221,7 +215,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -230,8 +223,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= @@ -374,7 +367,6 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/src/internal/app/event/order.go b/src/internal/app/event/order.go new file mode 100644 index 0000000..8eeb082 --- /dev/null +++ b/src/internal/app/event/order.go @@ -0,0 +1,10 @@ +package event + +const ( + EVENT_BASKET_CHECKOUT = "event.BasketCheckoutEvent" +) + +type BasketCheckoutEvent struct { + *Event + BasketID string `json:"basket_id"` +} diff --git a/src/internal/app/log.go b/src/internal/app/log.go new file mode 100644 index 0000000..1728b1a --- /dev/null +++ b/src/internal/app/log.go @@ -0,0 +1,20 @@ +package app + +import ( + "log" +) + +const AppName = "basket-svc" + +func Panic(v ...any) { + log.Panicln(AppName+":", v) +} + +func Panicf(format string, v ...any) { + log.Panicf(AppName+": "+format, v...) +} + +func Panicln(v ...any) { + v = append([]any{AppName + ":"}, v...) + log.Panicln(v...) +} diff --git a/src/internal/app/server/config.go b/src/internal/app/server/config.go index 89e4ea1..9bec52b 100644 --- a/src/internal/app/server/config.go +++ b/src/internal/app/server/config.go @@ -1,15 +1,22 @@ package server +import "fmt" + type Config struct { - AppName string - AppDomain string - NetAddr string - // Host string + AppID string + AppName string + AppDomain string + NetAddr string Port int LoggerAddr string + RegistryAddr string DbURL string MongoDbUrl string EventBusURL string EventBusExchange string EventBusQueue string } + +func (c *Config) GetAppFullName() string { + return fmt.Sprintf("%s_%s", c.AppName, c.AppID) +} diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go index 5af8f0f..3084073 100644 --- a/src/internal/app/server/server.go +++ b/src/internal/app/server/server.go @@ -3,6 +3,7 @@ package server import ( "os" "os/signal" + "syscall" "time" "github.com/gofiber/fiber/v2" @@ -15,32 +16,34 @@ import ( type Server struct { *fiber.App - log *fluentd.Logger - db *pgxpool.Pool - ebCh *amqp.Channel - name string - addr string + log *fluentd.Logger + db *pgxpool.Pool + ebCh *amqp.Channel + discovery *discovery.Service + name string + addr string } -type RequestID struct { +type Headers struct { RequestID string `reqHeader:"x-request-id"` } func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amqp.Channel) *Server { - discovery, err := discovery.NewService(conf.AppName, conf.AppDomain, conf.Port) + logger.Log("API_ID: %s", conf.AppID) + discovery, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.Port) if err != nil { - logger.Log("Error connecting to api-registry: %v", err) + logger.Log("Error connecting to %s: %v", conf.RegistryAddr, err) } logger.Log("Registering service with name: %s, address: %s", discovery.Name, discovery.Address) err = discovery.Register() if err != nil { - logger.Log(err.Error()) + logger.Log("register error: %v", err) } cnf := fiber.Config{ AppName: conf.AppName, - ServerHeader: conf.AppDomain, + ServerHeader: conf.AppName, ReadTimeout: time.Millisecond * 50, WriteTimeout: time.Millisecond * 50, IdleTimeout: time.Millisecond * 50, @@ -50,6 +53,7 @@ func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amq logger, db, ebCh, + discovery, conf.AppName, conf.NetAddr, } @@ -65,37 +69,43 @@ func (s *Server) Start() { s.log.Log("Starting error: %v", err) } -func (s *Server) StartWithGracefulShutdown() { - idle := make(chan struct{}) - +func (s *Server) StartWithGracefulShutdown(forever chan struct{}) { go func() { sigint := make(chan os.Signal, 1) - signal.Notify(sigint, os.Interrupt) + signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) <-sigint - if err := s.Shutdown(); err != nil { + if err := s.gracefulShutdown(); err != nil { s.log.Log("Server is not shutting down! Reason: %v", err) } - s.log.Log("Servier is going down...") - // remove info from registry and close all connection here... - - close(idle) + close(forever) }() if err := s.Listen(s.addr); err != nil { s.log.Log("Server is not running! Reason: %v", err) } - <-idle + <-forever } func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { - var hdr = new(RequestID) + var hdr = new(Headers) if err := c.ReqHeaderParser(hdr); err != nil { return "", err } return hdr.RequestID, nil - +} + +func (s *Server) gracefulShutdown() error { + s.log.Log("Server is going down...") + s.log.Log("Unregistering service: %s", s.discovery.GetID()) + s.discovery.Unregister() + + s.ebCh.Close() + s.db.Close() + s.log.Close() + + return s.Shutdown() } -- 2.39.5 From c931b14cb1a347f3e51efc81804fb6a2f1613dfd Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 2 Dec 2022 21:56:00 +0100 Subject: [PATCH 06/18] Skip logging of health check requests --- Dockerfile.target | 2 +- src/internal/app/server/router.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Dockerfile.target b/Dockerfile.target index 3c233b4..5e4d15f 100644 --- a/Dockerfile.target +++ b/Dockerfile.target @@ -11,7 +11,7 @@ ARG SVC_NAME ARG SVC_VER LABEL dev.egommerce.image.author="Piotr Biernat" -LABEL dev.egommerce.image.service="api-eventubus" +LABEL dev.egommerce.image.vendor="Egommerce" LABEL dev.egommerce.image.service=${SVC_NAME} LABEL dev.egommerce.image.version=${SVC_VER} diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go index 5ae3a37..823797e 100644 --- a/src/internal/app/server/router.go +++ b/src/internal/app/server/router.go @@ -1,6 +1,8 @@ package server import ( + "strings" + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" "github.com/gofiber/fiber/v2" ) @@ -21,6 +23,11 @@ func SetupMiddlewares(s *Server) { // Middlewares func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { + path := string(c.Request().URI().Path()) + if strings.Contains(path, "/health") { + return c.Next() + } + log.Log("Request: %s, remote: %s, via: %s", c.Request().URI().String(), c.Context().RemoteIP().String(), -- 2.39.5 From 7e938e3070f70e4bbbd40956699b5a526052bab6 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 2 Dec 2022 23:37:01 +0100 Subject: [PATCH 07/18] build fix --- deploy/image-push.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/deploy/image-push.sh b/deploy/image-push.sh index a4e3f11..19967b4 100755 --- a/deploy/image-push.sh +++ b/deploy/image-push.sh @@ -5,6 +5,8 @@ export IMAGE_BASE="git.pbiernat.dev/egommerce/order" export SERVER_IMAGE="$IMAGE_BASE-svc" export WORKER_IMAGE="$IMAGE_BASE-worker" +TARGET=${1:-latest} + echo $DOCKER_PASSWORD | docker login git.pbiernat.dev -u $DOCKER_USERNAME --password-stdin -docker push "$SERVER_IMAGE:latest" -docker push "$WORKER_IMAGE:latest" +docker push "$SERVER_IMAGE:$TARGET" +docker push "$WORKER_IMAGE:$TARGET" -- 2.39.5 From f2f8a40bd9e8d69a1223c07f888bbde5a75d9b6f Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Wed, 7 Dec 2022 02:51:47 +0100 Subject: [PATCH 08/18] Added wait-for-it.sh script and fetching config from consul KV store --- Dockerfile.target | 10 +- bin/entrypoint.sh | 25 ++++ bin/wait-for-it.sh | 165 ++++++++++++++++++++++ deploy/image-build.sh | 24 ++-- deploy/image-push.sh | 1 + src/cmd/server/main.go | 2 + src/cmd/worker/main.go | 42 ++++++ src/go.mod | 2 +- src/go.sum | 20 +-- src/internal/app/server/config.go | 30 ++-- src/internal/app/server/health_handler.go | 4 + src/internal/app/server/router.go | 5 +- src/internal/app/server/server.go | 43 +++++- 13 files changed, 330 insertions(+), 43 deletions(-) create mode 100755 bin/entrypoint.sh create mode 100755 bin/wait-for-it.sh diff --git a/Dockerfile.target b/Dockerfile.target index 5e4d15f..5dff45c 100644 --- a/Dockerfile.target +++ b/Dockerfile.target @@ -1,11 +1,12 @@ # Builder -ARG BUILDER_IMAGE="git.pbiernat.dev/egommerce/order-builder:latest" +ARG BUILDER_IMAGE FROM ${BUILDER_IMAGE} AS builder # Destination image - server # FROM gcr.io/distroless/base-debian10 FROM alpine:3.17 +ARG BUILD_TIME ARG BIN_OUTPUT ARG SVC_NAME ARG SVC_VER @@ -14,10 +15,15 @@ LABEL dev.egommerce.image.author="Piotr Biernat" LABEL dev.egommerce.image.vendor="Egommerce" LABEL dev.egommerce.image.service=${SVC_NAME} LABEL dev.egommerce.image.version=${SVC_VER} +LABEL dev.egommerce.image.build_time=${BUILD_TIME} WORKDIR / COPY --from=builder $BIN_OUTPUT /app COPY .env.dist /.env +COPY ./bin/entrypoint.sh ./bin/wait-for-it.sh / +RUN chmod 755 /entrypoint.sh EXPOSE 80 -ENTRYPOINT ["/app"] + +CMD ["/app"] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh new file mode 100755 index 0000000..f77e6fa --- /dev/null +++ b/bin/entrypoint.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env sh +set +e + +waitForService() +{ + ./wait-for-it.sh $1 -t 2 1>/dev/null 2>&1 + status=$? + while [ $status != 0 ] + do + echo "[x] wating for $1..." + sleep 1 + ./wait-for-it.sh $1 -t 2 1>/dev/null 2>&1 + status=$? + done +} + +waitForService "postgres-db:5432" +waitForService "api-eventbus:5672" +waitForService "api-logger:24224" +waitForService "api-registry:8500" + + +set -euo pipefail + +exec "$@" diff --git a/bin/wait-for-it.sh b/bin/wait-for-it.sh new file mode 100755 index 0000000..fff13c9 --- /dev/null +++ b/bin/wait-for-it.sh @@ -0,0 +1,165 @@ +#!/usr/bin/env sh +# Use this script to test if a given TCP host/port are available + +set -e + +cmdname=$(basename "$0") + +echoerr() { + if [ "$QUIET" -ne 1 ]; then + printf "%s\n" "$*" 1>&2; + fi +} + +usage() +{ + exitcode="$1" + cat << USAGE >&2 +Usage: + $cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit "$exitcode" +} + +wait_for() +{ + if [ "$TIMEOUT" -gt 0 ]; then + echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" + else + echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" + fi + start_ts=$(date +%s) + while true + do + nc -z "$HOST" "$PORT" >/dev/null 2>&1 + result=$? + if [ $result -eq 0 ]; then + end_ts=$(date +%s) + echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" + break + fi + sleep 1 + done + return $result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [ "$QUIET" -eq 1 ]; then + timeout "$TIMEOUT" "$0" -q -child "$HOST":"$PORT" -t "$TIMEOUT" & + else + timeout "$TIMEOUT" "$0" --child "$HOST":"$PORT" -t "$TIMEOUT" & + fi + PID=$! + trap 'kill -INT -$PID' INT + wait $PID + RESULT=$? + if [ $RESULT -ne 0 ]; then + echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" + fi + return $RESULT +} + +TIMEOUT=15 +STRICT=0 +CHILD=0 +QUIET=0 +# process arguments +while [ $# -gt 0 ] +do + case "$1" in + *:* ) + HOST=$(printf "%s\n" "$1"| cut -d : -f 1) + PORT=$(printf "%s\n" "$1"| cut -d : -f 2) + shift 1 + ;; + --child) + CHILD=1 + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -s | --strict) + STRICT=1 + shift 1 + ;; + -h) + HOST="$2" + if [ "$HOST" = "" ]; then break; fi + shift 2 + ;; + --host=*) + HOST=$(printf "%s" "$1" | cut -d = -f 2) + shift 1 + ;; + -p) + PORT="$2" + if [ "$PORT" = "" ]; then break; fi + shift 2 + ;; + --port=*) + PORT="${1#*=}" + shift 1 + ;; + -t) + TIMEOUT="$2" + if [ "$TIMEOUT" = "" ]; then break; fi + shift 2 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + break + ;; + --help) + usage 0 + ;; + *) + echoerr "Unknown argument: $1" + usage 1 + ;; + esac +done + +if [ "$HOST" = "" -o "$PORT" = "" ]; then + echoerr "Error: you need to provide a host and port to test." + usage 2 +fi + +if [ $CHILD -gt 0 ]; then + wait_for + RESULT=$? + exit $RESULT +else + if [ "$TIMEOUT" -gt 0 ]; then + wait_for_wrapper + RESULT=$? + else + wait_for + RESULT=$? + fi +fi + +if [ "$*" != "" ]; then + if [ $RESULT -ne 0 -a $STRICT -eq 1 ]; then + echoerr "$cmdname: strict mode, refusing to execute subprocess" + exit $RESULT + fi + exec "$@" +else + exit $RESULT +fi diff --git a/deploy/image-build.sh b/deploy/image-build.sh index 243f419..ecf2ca2 100755 --- a/deploy/image-build.sh +++ b/deploy/image-build.sh @@ -2,39 +2,39 @@ # RUN IN REPO ROOT DIR !! export IMAGE_PREFIX="git.pbiernat.dev/egommerce/order" -export BUILDER_IMAGE="$IMAGE_PREFIX-builder:tmp" +export BUILDER_IMAGE="egommerce-builder:order" +export BUILD_TIME=$(date +"%Y%m%d%H%M%S") export SERVER_IMAGE="$IMAGE_PREFIX-svc" export WORKER_IMAGE="$IMAGE_PREFIX-worker" +export DOCKER_BUILDKIT=1 TARGET=${1:-latest} -[ ! -d \"src/vendor\" ] && sh -c "cd src; go mod vendor" - -export DOCKER_BUILDKIT=1 - -docker build -t "$BUILDER_IMAGE" -f Dockerfile.builder . && echo "Successfully tagged $BUILDER_IMAGE" +[ ! -d "src/vendor" ] && sh -c "cd src; go mod vendor" echo "Building target $IMAGE_PREFIX images..." +docker build --rm -t "$BUILDER_IMAGE" -f Dockerfile.builder . + if [ $TARGET = "latest" ] then # SERVER docker build --build-arg SVC_NAME=order-svc --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/server \ - --rm --build-arg BUILDER_IMAGE --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" \ - -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & + --build-arg BUILDER_IMAGE=$BUILDER_IMAGE --build-arg BUILD_TIME --rm --cache-from "$SERVER_IMAGE:$TARGET" -t "$SERVER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" # WORKER docker build --build-arg SVC_NAME=order-worker --build-arg SVC_VER="1.0" --build-arg BIN_OUTPUT=/go/bin/worker \ - --rm --build-arg BUILDER_IMAGE --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" \ + --build-arg BUILDER_IMAGE=$BUILDER_IMAGE --build-arg BUILD_TIME --rm --cache-from "$WORKER_IMAGE:$TARGET" -t "$WORKER_IMAGE:$TARGET" \ -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" else # SERVER docker build --build-arg SVC_NAME=order-svc --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/server \ - --rm --build-arg BUILDER_IMAGE --no-cache -t "$SERVER_IMAGE:$TARGET" \ - -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" & + --build-arg BUILDER_IMAGE=$BUILDER_IMAGE --build-arg BUILD_TIME --rm --no-cache -t "$SERVER_IMAGE:$TARGET" \ + -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET" # WORKER docker build --build-arg SVC_NAME=order-worker --build-arg SVC_VER="dev" --build-arg BIN_OUTPUT=/go/bin/worker \ - --rm --build-arg BUILDER_IMAGE --no-cache -t "$WORKER_IMAGE:$TARGET" \ + --build-arg BUILDER_IMAGE=$BUILDER_IMAGE --build-arg BUILD_TIME --rm --no-cache -t "$WORKER_IMAGE:$TARGET" \ -f Dockerfile.target . >/dev/null 2>&1 && echo "Successfully tagged $WORKER_IMAGE:$TARGET" fi diff --git a/deploy/image-push.sh b/deploy/image-push.sh index 19967b4..bee5bd2 100755 --- a/deploy/image-push.sh +++ b/deploy/image-push.sh @@ -8,5 +8,6 @@ export WORKER_IMAGE="$IMAGE_BASE-worker" TARGET=${1:-latest} echo $DOCKER_PASSWORD | docker login git.pbiernat.dev -u $DOCKER_USERNAME --password-stdin + docker push "$SERVER_IMAGE:$TARGET" docker push "$WORKER_IMAGE:$TARGET" diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index 181ed88..2a98b25 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -23,6 +23,7 @@ const ( defEventBusURL = "amqp://guest:guest@api-eventbus:5672" ebEventsExchange = "api-events" ebEventsQueue = "order-svc" + defKVNmspc = "dev.egommerce/service/order-svc" ) func main() { @@ -41,6 +42,7 @@ func main() { c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) c.EventBusExchange = ebEventsExchange + c.KVNamespace = config.GetEnv("APP_KV_NAMESPACE", defKVNmspc) logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index 2b4ccc8..424521e 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -1,13 +1,18 @@ package main import ( + "bytes" + "encoding/json" + "errors" "fmt" "log" "os" "os/signal" "strings" "syscall" + "time" + discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/config" @@ -25,6 +30,7 @@ const ( defEventBusURL = "amqp://guest:guest@api-eventbus:5672" ebEventsExchange = "api-events" ebEventsQueue = "order-worker" + defKVNmspc = "dev.egommerce/service/order-worker" ) func main() { @@ -41,11 +47,28 @@ func main() { c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) c.EventBusExchange = ebEventsExchange c.EventBusQueue = ebEventsQueue + c.KVNamespace = config.GetEnv("APP_KV_NAMESPACE", defKVNmspc) logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) defer logger.Close() + consul, err := discovery.NewService(c.RegistryAddr, c.AppID, c.AppName, c.AppID, "", 0) + if err != nil { + logger.Log("Error connecting to %s: %v", c.RegistryAddr, err) + } + + go func(consul *discovery.Service) { + interval := time.Second * 3 + ticker := time.NewTicker(interval) + for range ticker.C { + err := updateKVConfig(consul, c) // FIXME: duplicated in internal/app/server/server.go + if err != nil { + logger.Log("KV config update error (skipping): %v\n", err) + } + } + }(consul) + // db conn dbConn, err := database.Connect(c.DbURL) if err != nil { // fixme: add wait-for-db... @@ -142,3 +165,22 @@ func main() { logger.Log("Waiting for messages...") <-forever } + +func updateKVConfig(s *discovery.Service, oldCnf *server.Config) error { // FIXME: duplicated in internal/app/server/server.go + data, _, err := s.KV().Get(oldCnf.KVNamespace, nil) + if err != nil { + return err + } + + if data == nil { + return errors.New("empty KV config data. Skipping") + } + + buf := bytes.NewBuffer(data.Value) + decoder := json.NewDecoder(buf) + if err := decoder.Decode(oldCnf); err != nil { + return err + } + + return nil +} diff --git a/src/go.mod b/src/go.mod index f828404..c77daf6 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,7 +3,7 @@ module git.pbiernat.dev/egommerce/order-service go 1.18 require ( - git.pbiernat.dev/egommerce/go-api-pkg v0.0.101 + git.pbiernat.dev/egommerce/go-api-pkg v0.0.108 github.com/gofiber/fiber/v2 v2.40.1 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 diff --git a/src/go.sum b/src/go.sum index 2bb5cb8..66b46ba 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,13 +1,13 @@ -git.pbiernat.dev/egommerce/go-api-pkg v0.0.32 h1:ArB/n30m927WMAM4u51guH+qR0Lu4NGyYnYdi7OhlzY= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.32/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.33 h1:1tm+pvUeS6OZLvHmLM3BwFS0Ty/eA3jDRuB60OicosA= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.33/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.34 h1:UO1x6O+cyU7yYYbDCDyhhAypuf4QGIXcmWcBEEjLuYM= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.34/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.100 h1:jw4fiGbZTsfJXJpGV+HQiYeMGZ7DMRMoepjuIwY6FIU= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.100/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.101 h1:NZCFAAlC94+LcN1gjrENnWUHvpWgaNksyB2N4Fiy8C4= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.101/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.103 h1:tVSHVQOBDe1Ofcbodaa/R5gHRD4gYO/d1tw7rVuLJuA= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.103/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.104 h1:YymR7Zyo9xjIZ9S75o2nfyNHp69n2FXHyGbTxtV1p/A= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.104/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.105 h1:8w4p4QNaSF58iL3YiGvqXC4UjUVeeu5D10OQmImA/Z0= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.105/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.106 h1:kOqDvQfk8MzmyQonMMLmZKhW7I5YeDyw6N8YIYHIVwA= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.106/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.108 h1:gr5kzKNR3sCxTz+nbqtOM7vdIely5ZWb8itSLAjTo0I= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.108/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= diff --git a/src/internal/app/server/config.go b/src/internal/app/server/config.go index 9bec52b..9fce58d 100644 --- a/src/internal/app/server/config.go +++ b/src/internal/app/server/config.go @@ -3,18 +3,24 @@ package server import "fmt" type Config struct { - AppID string - AppName string - AppDomain string - NetAddr string - Port int - LoggerAddr string - RegistryAddr string - DbURL string - MongoDbUrl string - EventBusURL string - EventBusExchange string - EventBusQueue string + AppID string + AppName string + AppDomain string + NetAddr string + Port int + RegistryAddr string + KVNamespace string + + LoggerAddr string `json:"logger_addr"` + DbURL string `json:"db_url"` + MongoDbUrl string `json:"mongodb_url"` + EventBusURL string `json:"eventbus_url"` + EventBusExchange string `json:"eventbus_exchange"` + EventBusQueue string `json:"eventbus_queue"` + HttpReadTimeout int `json:"http_read_timeout"` + HttpWriteTimeout int `json:"http_write_timeout"` + HttpIdleTimeout int `json:"http_idle_timeout"` + // Fields with json mapping are available trough ConsulKV } func (c *Config) GetAppFullName() string { diff --git a/src/internal/app/server/health_handler.go b/src/internal/app/server/health_handler.go index 9178d24..62573aa 100644 --- a/src/internal/app/server/health_handler.go +++ b/src/internal/app/server/health_handler.go @@ -11,3 +11,7 @@ func (s *Server) HealthHandler(c *fiber.Ctx) error { Status: "OK", }) } + +func (s *Server) ConfigHandler(c *fiber.Ctx) error { + return c.JSON(s.conf) +} diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go index 823797e..07fc399 100644 --- a/src/internal/app/server/router.go +++ b/src/internal/app/server/router.go @@ -8,12 +8,13 @@ import ( ) func SetupRoutes(s *Server) { + s.App.Get("/health", s.HealthHandler) + s.App.Get("/config", s.ConfigHandler) + api := s.App.Group("/api") v1 := api.Group("/v1") order := v1.Group("/order") order.Put("/:orderId/status", s.UpdateOrderStatusHandler) - - s.App.Get("/health", s.HealthHandler) } func SetupMiddlewares(s *Server) { diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go index 3084073..38761d7 100644 --- a/src/internal/app/server/server.go +++ b/src/internal/app/server/server.go @@ -1,6 +1,9 @@ package server import ( + "bytes" + "encoding/json" + "fmt" "os" "os/signal" "syscall" @@ -16,12 +19,14 @@ import ( type Server struct { *fiber.App + conf *Config log *fluentd.Logger db *pgxpool.Pool ebCh *amqp.Channel discovery *discovery.Service name string addr string + kvNmspc string } type Headers struct { @@ -30,13 +35,13 @@ type Headers struct { func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amqp.Channel) *Server { logger.Log("API_ID: %s", conf.AppID) - discovery, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.Port) + consul, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.Port) if err != nil { logger.Log("Error connecting to %s: %v", conf.RegistryAddr, err) } - logger.Log("Registering service with name: %s, address: %s", discovery.Name, discovery.Address) - err = discovery.Register() + logger.Log("Registering service with name: %s, address: %s", consul.Name, consul.Address) + err = consul.Register() if err != nil { logger.Log("register error: %v", err) } @@ -50,14 +55,27 @@ func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amq } s := &Server{ fiber.New(cnf), + conf, logger, db, ebCh, - discovery, + consul, conf.AppName, conf.NetAddr, + conf.KVNamespace, } + go func(s *Server) { // Consul KV config updater + interval := time.Second * 30 + ticker := time.NewTicker(interval) + for range ticker.C { + err := s.updateKVConfig() + if err != nil { + logger.Log("KV config update error (skipping): %v\n", err) + } + } + }(s) + SetupMiddlewares(s) SetupRoutes(s) @@ -98,6 +116,23 @@ func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { return hdr.RequestID, nil } +func (s *Server) updateKVConfig() error { // FIXME: duplicated in cmd/worker/main.go + data, _, err := s.discovery.KV().Get(s.kvNmspc, nil) + if err != nil { + fmt.Println(err) + + return err + } + + kvCnf := bytes.NewBuffer(data.Value) + decoder := json.NewDecoder(kvCnf) + if err := decoder.Decode(&s.conf); err != nil { + return err + } + + return nil +} + func (s *Server) gracefulShutdown() error { s.log.Log("Server is going down...") s.log.Log("Unregistering service: %s", s.discovery.GetID()) -- 2.39.5 From fa01f47baae0fbd4e0a0ccdb1ecf79c196e6aea3 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 16 Dec 2022 01:04:35 +0100 Subject: [PATCH 09/18] fixes --- src/cmd/worker/main.go | 2 +- src/go.mod | 2 +- src/go.sum | 2 ++ src/internal/app/server/server.go | 9 +++++++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index 424521e..aa8b30c 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -173,7 +173,7 @@ func updateKVConfig(s *discovery.Service, oldCnf *server.Config) error { // FIXM } if data == nil { - return errors.New("empty KV config data. Skipping") + return errors.New("empty KV config data") } buf := bytes.NewBuffer(data.Value) diff --git a/src/go.mod b/src/go.mod index c77daf6..d65c86e 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,7 +3,7 @@ module git.pbiernat.dev/egommerce/order-service go 1.18 require ( - git.pbiernat.dev/egommerce/go-api-pkg v0.0.108 + git.pbiernat.dev/egommerce/go-api-pkg v0.0.113 github.com/gofiber/fiber/v2 v2.40.1 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 diff --git a/src/go.sum b/src/go.sum index 66b46ba..8cec01a 100644 --- a/src/go.sum +++ b/src/go.sum @@ -8,6 +8,8 @@ git.pbiernat.dev/egommerce/go-api-pkg v0.0.106 h1:kOqDvQfk8MzmyQonMMLmZKhW7I5YeD git.pbiernat.dev/egommerce/go-api-pkg v0.0.106/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= git.pbiernat.dev/egommerce/go-api-pkg v0.0.108 h1:gr5kzKNR3sCxTz+nbqtOM7vdIely5ZWb8itSLAjTo0I= git.pbiernat.dev/egommerce/go-api-pkg v0.0.108/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.113 h1:kf7HesezhXIAMNYgLCm8x6YVqyLqJRqaPKIFEXf4xSs= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.113/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go index 38761d7..f7bb0df 100644 --- a/src/internal/app/server/server.go +++ b/src/internal/app/server/server.go @@ -3,6 +3,7 @@ package server import ( "bytes" "encoding/json" + "errors" "fmt" "os" "os/signal" @@ -117,14 +118,18 @@ func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { } func (s *Server) updateKVConfig() error { // FIXME: duplicated in cmd/worker/main.go - data, _, err := s.discovery.KV().Get(s.kvNmspc, nil) + config, _, err := s.discovery.KV().Get(s.kvNmspc, nil) if err != nil { fmt.Println(err) return err } - kvCnf := bytes.NewBuffer(data.Value) + if config == nil { + return errors.New("empty KV config data") + } + + kvCnf := bytes.NewBuffer(config.Value) decoder := json.NewDecoder(kvCnf) if err := decoder.Decode(&s.conf); err != nil { return err -- 2.39.5 From f03215cfd807f5c8993fb8425c6afcb605119009 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Sat, 17 Dec 2022 08:26:32 +0100 Subject: [PATCH 10/18] Added migrations --- Dockerfile.builder | 2 + Dockerfile.target | 7 +- bin/entrypoint.sh | 8 +- bin/migrate.sh | 26 ++++++ src/cmd/migrate/main.go | 88 +++++++++++++++++++ src/cmd/worker/main.go | 5 +- src/go.mod | 10 +++ src/go.sum | 135 +++++++++++++++++++++++++++--- src/internal/app/log.go | 2 +- src/internal/app/server/server.go | 5 +- 10 files changed, 263 insertions(+), 25 deletions(-) create mode 100644 bin/migrate.sh create mode 100644 src/cmd/migrate/main.go diff --git a/Dockerfile.builder b/Dockerfile.builder index 779d27f..6ccc27d 100644 --- a/Dockerfile.builder +++ b/Dockerfile.builder @@ -3,6 +3,7 @@ FROM golang:alpine ARG BIN_OUTPUT=/go/bin ARG GO_SERVER=cmd/server/main.go +ARG GO_MIGRATE=cmd/migrate/main.go ARG GO_WORKER=cmd/worker/main.go WORKDIR /go/src/app @@ -10,4 +11,5 @@ COPY src ./ RUN export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ go build -ldflags="-w -s" -o "$BIN_OUTPUT/server" $GO_SERVER && \ + go build -ldflags="-w -s" -o "$BIN_OUTPUT/migrate" $GO_MIGRATE && \ go build -ldflags="-w -s" -o "$BIN_OUTPUT/worker" $GO_WORKER diff --git a/Dockerfile.target b/Dockerfile.target index 5dff45c..944c9ce 100644 --- a/Dockerfile.target +++ b/Dockerfile.target @@ -19,11 +19,12 @@ LABEL dev.egommerce.image.build_time=${BUILD_TIME} WORKDIR / COPY --from=builder $BIN_OUTPUT /app +COPY --from=builder /go/bin/migrate /bin/go_migrate COPY .env.dist /.env -COPY ./bin/entrypoint.sh ./bin/wait-for-it.sh / -RUN chmod 755 /entrypoint.sh +COPY ./bin /bin +RUN chmod 755 /bin/entrypoint.sh /bin/migrate.sh EXPOSE 80 CMD ["/app"] -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["entrypoint.sh"] diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index f77e6fa..01a6dc9 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -3,13 +3,13 @@ set +e waitForService() { - ./wait-for-it.sh $1 -t 2 1>/dev/null 2>&1 + wait-for-it.sh $1 -t 2 1>/dev/null 2>&1 status=$? while [ $status != 0 ] do echo "[x] wating for $1..." sleep 1 - ./wait-for-it.sh $1 -t 2 1>/dev/null 2>&1 + wait-for-it.sh $1 -t 2 1>/dev/null 2>&1 status=$? done } @@ -19,7 +19,9 @@ waitForService "api-eventbus:5672" waitForService "api-logger:24224" waitForService "api-registry:8500" +# run migrations +migrate.sh -set -euo pipefail +# set -euo pipefail exec "$@" diff --git a/bin/migrate.sh b/bin/migrate.sh new file mode 100644 index 0000000..e2980b8 --- /dev/null +++ b/bin/migrate.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env sh + +# ensure migrate env is initialized +$(go_migrate version >/dev/null 2>&1) +version=$? +if [ $version != "0" ] +then + echo "Creating base table..." + $(go_migrate init >/dev/null 2>&1) + init=$? +fi + +# check again +$(go_migrate version >/dev/null 2>&1) +version=$? +if [ $version != "0" ] +then + echo "Unable to run migrations." + exit 1 +fi + +# run migrations +go_migrate up +echo "Done." + +exit $version diff --git a/src/cmd/migrate/main.go b/src/cmd/migrate/main.go new file mode 100644 index 0000000..c3410c5 --- /dev/null +++ b/src/cmd/migrate/main.go @@ -0,0 +1,88 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + + "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" + "git.pbiernat.dev/egommerce/order-service/internal/app/config" + "github.com/go-pg/migrations/v8" + "github.com/go-pg/pg/v10" +) + +const ( + defAppName = "order-svc-migrations" + defMigrationsTableName = `"order".migrations` + defLoggerAddr = "api-logger:24224" + // defKVNmspc = "dev.egommerce/service/order-migration" +) + +const usageText = `This program runs command on the db. Supported commands are: + - init - creates version info table in the database + - up - runs all available migrations. + - up [target] - runs available migrations up to the target one. + - down - reverts last migration. + - reset - reverts all migrations. + - version - prints current db version. + - set_version [version] - sets db version without running migrations. +Usage: + go run cmd/migrate/main.go [args] +` + +func main() { + if config.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + } + + // dbURL := config.GetEnv("DATABASE_URL", defDbURL) + loggerAddr := config.GetEnv("LOGGER_ADDR", defLoggerAddr) + mTblName := config.GetEnv("MIGRATIONS_TABLE_NAME", defMigrationsTableName) + + logHost, logPort := fluentd.ParseAddr(loggerAddr) + logger := fluentd.NewLogger(defAppName, logHost, logPort) + defer logger.Close() + + flag.Usage = usage + flag.Parse() + + db := pg.Connect(&pg.Options{ // FIXME + Addr: "postgres-db:5432", + User: "postgres", + Password: "12345678", + Database: "egommerce", + }) + + mig := migrations.NewCollection() + mig.SetTableName(mTblName) + err := mig.DiscoverSQLMigrations("./migrations") + if err != nil { + fmt.Println(err) + } + + oldVersion, newVersion, err := mig.Run(db, flag.Args()...) + if err != nil { + exitf(err.Error()) + } + if newVersion != oldVersion { + fmt.Printf("migrated from version %d to %d\n", oldVersion, newVersion) + } else { + fmt.Printf("version is %d\n", oldVersion) + } +} + +func usage() { + fmt.Print(usageText) + flag.PrintDefaults() + os.Exit(2) +} + +func errorf(s string, args ...interface{}) { + fmt.Fprintf(os.Stderr, s+"\n", args...) +} + +func exitf(s string, args ...interface{}) { + errorf(s, args...) + os.Exit(1) +} diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index aa8b30c..1392ae5 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -62,10 +62,7 @@ func main() { interval := time.Second * 3 ticker := time.NewTicker(interval) for range ticker.C { - err := updateKVConfig(consul, c) // FIXME: duplicated in internal/app/server/server.go - if err != nil { - logger.Log("KV config update error (skipping): %v\n", err) - } + updateKVConfig(consul, c) // FIXME: duplicated in internal/app/server/server.go } }(consul) diff --git a/src/go.mod b/src/go.mod index d65c86e..c8395c9 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,6 +4,8 @@ go 1.18 require ( git.pbiernat.dev/egommerce/go-api-pkg v0.0.113 + github.com/go-pg/migrations/v8 v8.1.0 + github.com/go-pg/pg/v10 v10.10.7 github.com/gofiber/fiber/v2 v2.40.1 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 @@ -15,6 +17,7 @@ require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fluent/fluent-logger-golang v1.9.0 // indirect + github.com/go-pg/zerochecker v0.2.0 // indirect github.com/hashicorp/consul/api v1.18.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.3.1 // indirect @@ -30,6 +33,7 @@ require ( github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect github.com/jackc/pgtype v1.12.0 // indirect github.com/jackc/puddle v1.3.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect @@ -39,10 +43,16 @@ require ( github.com/philhofer/fwd v1.1.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/tinylib/msgp v1.1.6 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.41.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect + github.com/vmihailenco/bufpool v0.1.11 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect + github.com/vmihailenco/tagparser v0.1.2 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.3.7 // indirect + mellium.im/sasl v0.2.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index 8cec01a..d274bae 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,13 +1,4 @@ -git.pbiernat.dev/egommerce/go-api-pkg v0.0.103 h1:tVSHVQOBDe1Ofcbodaa/R5gHRD4gYO/d1tw7rVuLJuA= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.103/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.104 h1:YymR7Zyo9xjIZ9S75o2nfyNHp69n2FXHyGbTxtV1p/A= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.104/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.105 h1:8w4p4QNaSF58iL3YiGvqXC4UjUVeeu5D10OQmImA/Z0= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.105/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.106 h1:kOqDvQfk8MzmyQonMMLmZKhW7I5YeDyw6N8YIYHIVwA= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.106/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.108 h1:gr5kzKNR3sCxTz+nbqtOM7vdIely5ZWb8itSLAjTo0I= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.108/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= git.pbiernat.dev/egommerce/go-api-pkg v0.0.113 h1:kf7HesezhXIAMNYgLCm8x6YVqyLqJRqaPKIFEXf4xSs= git.pbiernat.dev/egommerce/go-api-pkg v0.0.113/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -30,9 +21,11 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -42,31 +35,59 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= github.com/fluent/fluent-logger-golang v1.9.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-pg/migrations/v8 v8.1.0 h1:bc1wQwFoWRKvLdluXCRFRkeaw9xDU4qJ63uCAagh66w= +github.com/go-pg/migrations/v8 v8.1.0/go.mod h1:o+CN1u572XHphEHZyK6tqyg2GDkRvL2bIoLNyGIewus= +github.com/go-pg/pg/v10 v10.4.0/go.mod h1:BfgPoQnD2wXNd986RYEHzikqv9iE875PrFaZ9vXvtNM= +github.com/go-pg/pg/v10 v10.10.7 h1:Q7Bs45kP9MIg03v/ejwdqsPd1T0cecgeDoTJVg/UJuQ= +github.com/go-pg/pg/v10 v10.10.7/go.mod h1:GLmFXufrElQHf5uzM3BQlcfwV3nsgnHue5uzjQ6Nqxg= +github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= +github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -114,6 +135,7 @@ github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -162,6 +184,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -225,6 +249,18 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -243,6 +279,7 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= @@ -277,6 +314,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -284,6 +322,8 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -291,8 +331,20 @@ github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6 github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= +github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= +github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1/go.mod h1:xlngVLeyQ/Qi05oQxhQ+oTuqa03RjMwMfk/7/TCs+QI= +github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc= +github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= +github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -305,6 +357,7 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -312,23 +365,40 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= @@ -336,6 +406,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -343,7 +415,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -351,20 +425,28 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210923061019-b8560ed6a9b7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -383,8 +465,11 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -400,18 +485,48 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= +mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= diff --git a/src/internal/app/log.go b/src/internal/app/log.go index 1728b1a..c070f5d 100644 --- a/src/internal/app/log.go +++ b/src/internal/app/log.go @@ -4,7 +4,7 @@ import ( "log" ) -const AppName = "basket-svc" +const AppName = "order-svc" func Panic(v ...any) { log.Panicln(AppName+":", v) diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go index f7bb0df..2276fbb 100644 --- a/src/internal/app/server/server.go +++ b/src/internal/app/server/server.go @@ -70,10 +70,7 @@ func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amq interval := time.Second * 30 ticker := time.NewTicker(interval) for range ticker.C { - err := s.updateKVConfig() - if err != nil { - logger.Log("KV config update error (skipping): %v\n", err) - } + s.updateKVConfig() } }(s) -- 2.39.5 From 6c299458319b81624466713b36a0469415d639e8 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Sun, 25 Dec 2022 21:06:23 +0100 Subject: [PATCH 11/18] Refactoring --- bin/entrypoint.sh | 1 + src/cmd/migrate/main.go | 2 +- src/cmd/server/main.go | 17 ++++- src/cmd/worker/main.go | 73 ++++++++++++++------- src/go.mod | 8 ++- src/go.sum | 25 +++++-- src/internal/app/definition/error.go | 9 --- src/internal/app/definition/health.go | 5 -- src/internal/app/definition/order_status.go | 8 --- src/internal/app/server/config.go | 3 + src/internal/app/server/health_handler.go | 2 +- src/internal/app/server/order_handler.go | 23 ++++--- src/internal/app/server/router.go | 13 ++++ src/internal/app/server/server.go | 64 +++++++++++++----- src/internal/app/service/order.go | 56 ++++++++++++++-- src/internal/app/ui/order.go | 31 +++++++++ 16 files changed, 252 insertions(+), 88 deletions(-) delete mode 100644 src/internal/app/definition/error.go delete mode 100644 src/internal/app/definition/health.go delete mode 100644 src/internal/app/definition/order_status.go create mode 100644 src/internal/app/ui/order.go diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 01a6dc9..3cea32c 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -18,6 +18,7 @@ waitForService "postgres-db:5432" waitForService "api-eventbus:5672" waitForService "api-logger:24224" waitForService "api-registry:8500" +waitForService "basket-svc:80" # run migrations migrate.sh diff --git a/src/cmd/migrate/main.go b/src/cmd/migrate/main.go index c3410c5..5eb9e54 100644 --- a/src/cmd/migrate/main.go +++ b/src/cmd/migrate/main.go @@ -14,7 +14,7 @@ import ( const ( defAppName = "order-svc-migrations" - defMigrationsTableName = `"order".migrations` + defMigrationsTableName = "ordering.migrations" defLoggerAddr = "api-logger:24224" // defKVNmspc = "dev.egommerce/service/order-migration" ) diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index 2a98b25..3c35036 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -10,15 +10,19 @@ import ( "git.pbiernat.dev/egommerce/order-service/internal/app/config" "git.pbiernat.dev/egommerce/order-service/internal/app/database" "git.pbiernat.dev/egommerce/order-service/internal/app/server" + "github.com/go-redis/redis/v8" ) const ( defAppName = "order-svc" defAppDomain = "order-svc" + defPathPrefix = "/order" defNetAddr = ":80" defLoggerAddr = "api-logger:24224" defRegistryAddr = "api-registry:8500" defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" + defCacheAddr = "api-cache:6379" + defCachePassword = "12345678" defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" defEventBusURL = "amqp://guest:guest@api-eventbus:5672" ebEventsExchange = "api-events" @@ -35,11 +39,14 @@ func main() { c.AppID, _ = os.Hostname() c.AppName = config.GetEnv("APP_NAME", defAppName) c.AppDomain = config.GetEnv("APP_DOMAIN", defAppDomain) + c.PathPrefix = config.GetEnv("APP_PATH_PREFIX", defPathPrefix) c.NetAddr = config.GetEnv("SERVER_ADDR", defNetAddr) c.Port, _ = strconv.Atoi(c.NetAddr[1:]) c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) + c.CacheAddr = config.GetEnv("CACHE_ADDR", defCacheAddr) + c.CachePassword = config.GetEnv("CACHE_PASSWORD", defCachePassword) c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) c.EventBusExchange = ebEventsExchange c.KVNamespace = config.GetEnv("APP_KV_NAMESPACE", defKVNmspc) @@ -56,6 +63,14 @@ func main() { } defer dbConn.Close() + // redis conn + redis := redis.NewClient(&redis.Options{ + Addr: c.CacheAddr, + Password: c.CachePassword, + DB: 0, + }) + defer redis.Close() + // eventbus conn ebConn, ebCh, err := amqp.Open(c.EventBusURL) if err != nil { @@ -72,7 +87,7 @@ func main() { } // start server - srv := server.NewServer(c, logger, dbConn, ebCh) + srv := server.NewServer(c, logger, dbConn, redis, ebCh) forever := make(chan struct{}) srv.StartWithGracefulShutdown(forever) diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index 1392ae5..0d20002 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -14,11 +14,15 @@ import ( discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" + "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/config" "git.pbiernat.dev/egommerce/order-service/internal/app/database" "git.pbiernat.dev/egommerce/order-service/internal/app/event" "git.pbiernat.dev/egommerce/order-service/internal/app/server" + "git.pbiernat.dev/egommerce/order-service/internal/app/service" + "git.pbiernat.dev/egommerce/order-service/internal/app/ui" + "github.com/go-redis/redis/v8" + "github.com/streadway/amqp" ) const ( @@ -26,6 +30,8 @@ const ( defLoggerAddr = "api-logger:24224" defRegistryAddr = "api-registry:8500" defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" + defCacheAddr = "api-cache:6379" + defCachePassword = "12345678" defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" defEventBusURL = "amqp://guest:guest@api-eventbus:5672" ebEventsExchange = "api-events" @@ -44,6 +50,8 @@ func main() { c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) + c.CacheAddr = config.GetEnv("CACHE_ADDR", defCacheAddr) + c.CachePassword = config.GetEnv("CACHE_PASSWORD", defCachePassword) c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) c.EventBusExchange = ebEventsExchange c.EventBusQueue = ebEventsQueue @@ -53,7 +61,7 @@ func main() { logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) defer logger.Close() - consul, err := discovery.NewService(c.RegistryAddr, c.AppID, c.AppName, c.AppID, "", 0) + consul, err := discovery.NewService(c.RegistryAddr, c.AppID, c.AppName, c.AppID, "", "", 0) if err != nil { logger.Log("Error connecting to %s: %v", c.RegistryAddr, err) } @@ -74,16 +82,24 @@ func main() { } defer dbConn.Close() + // redis conn + redis := redis.NewClient(&redis.Options{ + Addr: c.CacheAddr, + Password: c.CachePassword, + DB: 0, + }) + defer redis.Close() + // eventbus conn - ebConn, ebCh, err := amqp.Open(c.EventBusURL) + ebConn, ebCh, err := rabbitmq.Open(c.EventBusURL) if err != nil { logger.Log("Failed to connect to EventBus server: %v\n", err) os.Exit(1) } defer ebCh.Close() - defer amqp.Close(ebConn) + defer rabbitmq.Close(ebConn) - err = amqp.NewExchange(ebCh, c.EventBusExchange) + err = rabbitmq.NewExchange(ebCh, c.EventBusExchange) if err != nil { logger.Log("Failed to declare EventBus exchange: %v\n", err) os.Exit(1) @@ -103,7 +119,7 @@ func main() { os.Exit(1) } - amqp.BindQueueToExchange(ebCh, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") + rabbitmq.BindQueueToExchange(ebCh, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") // if err != nil { // logger.Log("Failed to prepare EventBus queue: %v\n", err) // os.Exit(1) @@ -136,26 +152,39 @@ func main() { }() go func() { + orderSrv := service.NewOrderService(dbConn, redis, ebCh, logger) + for d := range msgs { - msg, err := amqp.Deserialize(d.Body) - if err != nil { - logger.Log("json error: %v\n", err) - d.Reject(false) // FIXME: how to handle erros in queue...???? - continue - } + go func(d amqp.Delivery) { + msg, err := rabbitmq.Deserialize(d.Body) + if err != nil { + logger.Log("deserialize error: %v\n", err) + d.Reject(false) // FIXME: how to handle erros in queue...???? + return + } - eName := fmt.Sprintf("%s", msg["event"]) - data := (msg["data"]).(map[string]interface{}) - logger.Log("Message<%s>: %s\n", eName, data) + eName := fmt.Sprintf("%s", msg["event"]) + data := (msg["data"]).(map[string]interface{}) + logger.Log("Message<%s>: %s\n", eName, data) - switch true { - case strings.Contains(eName, event.EVENT_BASKET_CHECKOUT): - // create new order based on basket - logger.Log("Event: %s", event.EVENT_BASKET_CHECKOUT) - } + reqID := data["request_id"].(string) // FIXME Check input params! - logger.Log("ACK: %s", eName) - d.Ack(false) + switch true { + case strings.Contains(eName, event.EVENT_BASKET_CHECKOUT): + basketID := data["basket_id"].(string) // FIXME Check input params! + // create new order based on basket + order, err := ui.CreateOrder(orderSrv, basketID, reqID) + if err != nil { + logger.Log("%s error: %v", event.EVENT_BASKET_CHECKOUT, err) + d.Reject(false) // FIXME: or Nack? how to handle erros in queue... + break + } + logger.Log("Event: %s. Created Order: %v", event.EVENT_BASKET_CHECKOUT, order) + } + + logger.Log("ACK: %s", eName) + d.Ack(false) + }(d) } }() diff --git a/src/go.mod b/src/go.mod index c8395c9..eebbae8 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,9 +3,11 @@ module git.pbiernat.dev/egommerce/order-service go 1.18 require ( - git.pbiernat.dev/egommerce/go-api-pkg v0.0.113 + git.pbiernat.dev/egommerce/api-entities v0.0.26 + git.pbiernat.dev/egommerce/go-api-pkg v0.0.136 github.com/go-pg/migrations/v8 v8.1.0 github.com/go-pg/pg/v10 v10.10.7 + github.com/go-redis/redis/v8 v8.11.5 github.com/gofiber/fiber/v2 v2.40.1 github.com/jackc/pgx/v4 v4.17.2 github.com/joho/godotenv v1.4.0 @@ -15,6 +17,8 @@ require ( require ( github.com/andybalholm/brotli v1.0.4 // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fatih/color v1.13.0 // indirect github.com/fluent/fluent-logger-golang v1.9.0 // indirect github.com/go-pg/zerochecker v0.2.0 // indirect @@ -31,7 +35,7 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgproto3/v2 v2.3.1 // indirect github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect - github.com/jackc/pgtype v1.12.0 // indirect + github.com/jackc/pgtype v1.13.0 // indirect github.com/jackc/puddle v1.3.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect diff --git a/src/go.sum b/src/go.sum index d274bae..75a263e 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.113 h1:kf7HesezhXIAMNYgLCm8x6YVqyLqJRqaPKIFEXf4xSs= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.113/go.mod h1:nAwcw2MZtn/54YKq8VQK6RJAsiuoLUtPuazXg8JcqK8= +git.pbiernat.dev/egommerce/api-entities v0.0.26 h1:Avz02GINwuYWOjw1fmZIJ3QgGEIz3a5vRQZNaxxUQIk= +git.pbiernat.dev/egommerce/api-entities v0.0.26/go.mod h1:+BXvUcr6Cr6QNpJsW8BUfe1vVILdWDADNE0e3u0lNvU= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.135 h1:qOa6MB6d2/lr0t9c3WWP84rf/T57PNYgizTmuNCDws8= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.135/go.mod h1:w2N79aoumjrrcrGPJLkCwxAHtrLd7G4Uj8VOxvPooa0= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.136 h1:SzJRAkqJKdng/3d0V7o/R0yGh7QaZynPBn/P++on9RA= +git.pbiernat.dev/egommerce/go-api-pkg v0.0.136/go.mod h1:w2N79aoumjrrcrGPJLkCwxAHtrLd7G4Uj8VOxvPooa0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -23,6 +27,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -35,6 +41,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -59,6 +67,8 @@ github.com/go-pg/pg/v10 v10.10.7 h1:Q7Bs45kP9MIg03v/ejwdqsPd1T0cecgeDoTJVg/UJuQ= github.com/go-pg/pg/v10 v10.10.7/go.mod h1:GLmFXufrElQHf5uzM3BQlcfwV3nsgnHue5uzjQ6Nqxg= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= @@ -171,8 +181,9 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.13.0 h1:XkIc7A+1BmZD19bB2NxrtjJweHxQ9agqvM+9URc68Cg= +github.com/jackc/pgtype v1.13.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= @@ -251,16 +262,16 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -520,8 +531,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/internal/app/definition/error.go b/src/internal/app/definition/error.go deleted file mode 100644 index 28f7dbf..0000000 --- a/src/internal/app/definition/error.go +++ /dev/null @@ -1,9 +0,0 @@ -package definition - -type ErrorResponse struct { - Error string `json:"error"` -} - -func Error(err string) *ErrorResponse { - return &ErrorResponse{err} -} diff --git a/src/internal/app/definition/health.go b/src/internal/app/definition/health.go deleted file mode 100644 index 6920fca..0000000 --- a/src/internal/app/definition/health.go +++ /dev/null @@ -1,5 +0,0 @@ -package definition - -type HealthResponse struct { - Status string `json:"status,omitempty"` -} diff --git a/src/internal/app/definition/order_status.go b/src/internal/app/definition/order_status.go deleted file mode 100644 index 3345ffb..0000000 --- a/src/internal/app/definition/order_status.go +++ /dev/null @@ -1,8 +0,0 @@ -package definition - -type UpdateOrderStatusRequest struct { - Status string `json:"status"` -} - -type UpdateOrderStatusResponse struct { -} diff --git a/src/internal/app/server/config.go b/src/internal/app/server/config.go index 9fce58d..5213283 100644 --- a/src/internal/app/server/config.go +++ b/src/internal/app/server/config.go @@ -6,6 +6,7 @@ type Config struct { AppID string AppName string AppDomain string + PathPrefix string NetAddr string Port int RegistryAddr string @@ -13,6 +14,8 @@ type Config struct { LoggerAddr string `json:"logger_addr"` DbURL string `json:"db_url"` + CacheAddr string `json:"cache_addr"` + CachePassword string `json:"cache_password"` MongoDbUrl string `json:"mongodb_url"` EventBusURL string `json:"eventbus_url"` EventBusExchange string `json:"eventbus_exchange"` diff --git a/src/internal/app/server/health_handler.go b/src/internal/app/server/health_handler.go index 62573aa..73d756e 100644 --- a/src/internal/app/server/health_handler.go +++ b/src/internal/app/server/health_handler.go @@ -3,7 +3,7 @@ package server import ( "github.com/gofiber/fiber/v2" - def "git.pbiernat.dev/egommerce/order-service/internal/app/definition" + def "git.pbiernat.dev/egommerce/api-entities/http" ) func (s *Server) HealthHandler(c *fiber.Ctx) error { diff --git a/src/internal/app/server/order_handler.go b/src/internal/app/server/order_handler.go index 3493b88..4b14e28 100644 --- a/src/internal/app/server/order_handler.go +++ b/src/internal/app/server/order_handler.go @@ -5,26 +5,29 @@ import ( "github.com/gofiber/fiber/v2" - def "git.pbiernat.dev/egommerce/order-service/internal/app/definition" + def "git.pbiernat.dev/egommerce/api-entities/http" "git.pbiernat.dev/egommerce/order-service/internal/app/service" + "git.pbiernat.dev/egommerce/order-service/internal/app/ui" ) func (s *Server) UpdateOrderStatusHandler(c *fiber.Ctx) error { reqID, _ := s.GetRequestID(c) - data := new(def.UpdateOrderStatusRequest) - if err := c.BodyParser(data); err != nil { - return err + req := new(def.UpdateOrderStatusRequest) + if err := c.BodyParser(req); err != nil { + return s.Error400(c, err.Error()) } // check if order exists in DB service... - orderId := c.Params("orderId") - var err error - if orderId == "" || err != nil { - return c.SendStatus(http.StatusBadRequest) + orderID := c.Params("orderId", "") + if orderID == "" { + return s.Error400(c, "") } - order := service.NewOrderService(s.ebCh, s.log) - order.UpdateOrderStatus(reqID, orderId, data.Status) + orderSrv := service.NewOrderService(s.db, s.cache, s.ebCh, s.log) + _, err := ui.UpdateOrderStatus(orderSrv, req.Status, orderID, reqID) + if err != nil { + return s.Error400(c, "Failed to update order status") + } return c.SendStatus(http.StatusNoContent) } diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go index 07fc399..da4ac45 100644 --- a/src/internal/app/server/router.go +++ b/src/internal/app/server/router.go @@ -5,9 +5,21 @@ import ( "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/cors" +) + +var ( + defaultCORS = cors.New(cors.Config{ + AllowOrigins: "*", + AllowCredentials: true, + AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS", + AllowHeaders: "Accept, Authorization, Content-Type, Vary, X-Request-Id", + }) ) func SetupRoutes(s *Server) { + s.App.Options("*", defaultCORS) + s.App.Get("/health", s.HealthHandler) s.App.Get("/config", s.ConfigHandler) @@ -18,6 +30,7 @@ func SetupRoutes(s *Server) { } func SetupMiddlewares(s *Server) { + s.App.Use(defaultCORS) s.App.Use(LoggingMiddleware(s.log)) } diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go index 2276fbb..ea7342d 100644 --- a/src/internal/app/server/server.go +++ b/src/internal/app/server/server.go @@ -2,18 +2,19 @@ package server import ( "bytes" + "context" "encoding/json" - "errors" - "fmt" "os" "os/signal" "syscall" "time" + "github.com/go-redis/redis/v8" "github.com/gofiber/fiber/v2" "github.com/jackc/pgx/v4/pgxpool" "github.com/streadway/amqp" + def "git.pbiernat.dev/egommerce/api-entities/http" discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" ) @@ -23,6 +24,7 @@ type Server struct { conf *Config log *fluentd.Logger db *pgxpool.Pool + cache *redis.Client ebCh *amqp.Channel discovery *discovery.Service name string @@ -34,9 +36,8 @@ type Headers struct { RequestID string `reqHeader:"x-request-id"` } -func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amqp.Channel) *Server { - logger.Log("API_ID: %s", conf.AppID) - consul, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.Port) +func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, cache *redis.Client, ebCh *amqp.Channel) *Server { + consul, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.PathPrefix, conf.Port) if err != nil { logger.Log("Error connecting to %s: %v", conf.RegistryAddr, err) } @@ -59,6 +60,7 @@ func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amq conf, logger, db, + cache, ebCh, consul, conf.AppName, @@ -67,13 +69,21 @@ func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, ebCh *amq } go func(s *Server) { // Consul KV config updater - interval := time.Second * 30 + interval := time.Second * 15 ticker := time.NewTicker(interval) for range ticker.C { s.updateKVConfig() } }(s) + go func(s *Server) { // Server metadata cache updater + interval := time.Second * 5 + ticker := time.NewTicker(interval) + for range ticker.C { + s.cacheMetadata() + } + }(s) + SetupMiddlewares(s) SetupRoutes(s) @@ -114,31 +124,51 @@ func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { return hdr.RequestID, nil } -func (s *Server) updateKVConfig() error { // FIXME: duplicated in cmd/worker/main.go +func (s *Server) Error400(c *fiber.Ctx, msg string) error { + return c.Status(fiber.StatusBadRequest).JSON(&def.ErrorResponse{Error: msg}) +} + +func (s *Server) Error404(c *fiber.Ctx, msg string) error { + return c.Status(fiber.StatusNotFound).JSON(&def.ErrorResponse{Error: msg}) +} + +func (s *Server) updateKVConfig() { // FIXME: duplicated in cmd/worker/main.go config, _, err := s.discovery.KV().Get(s.kvNmspc, nil) - if err != nil { - fmt.Println(err) - - return err - } - - if config == nil { - return errors.New("empty KV config data") + if err != nil || config == nil { + return } kvCnf := bytes.NewBuffer(config.Value) decoder := json.NewDecoder(kvCnf) if err := decoder.Decode(&s.conf); err != nil { - return err + return + } +} + +func (s *Server) cacheMetadata() { + ctx := context.Background() + key, address := "internal__"+s.conf.AppName+"__ips", s.conf.AppID // FIXME: key name + + pos := s.cache.LPos(ctx, key, address, redis.LPosArgs{}).Val() + if pos >= 0 { + s.cache.LRem(ctx, key, 0, address) } - return nil + s.cache.LPush(ctx, key, address).Err() +} + +func (s *Server) clearMetadataCache() { + ctx := context.Background() + key, address := "internal__"+s.conf.AppName+"__ips", s.conf.AppID // FIXME: key name + + s.cache.LRem(ctx, key, 0, address) } func (s *Server) gracefulShutdown() error { s.log.Log("Server is going down...") s.log.Log("Unregistering service: %s", s.discovery.GetID()) s.discovery.Unregister() + s.clearMetadataCache() s.ebCh.Close() s.db.Close() diff --git a/src/internal/app/service/order.go b/src/internal/app/service/order.go index 99a02ed..3b65f38 100644 --- a/src/internal/app/service/order.go +++ b/src/internal/app/service/order.go @@ -1,27 +1,73 @@ package service import ( + "context" + + "git.pbiernat.dev/egommerce/api-entities/model" + "git.pbiernat.dev/egommerce/go-api-pkg/api" "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" "git.pbiernat.dev/egommerce/order-service/internal/app/event" + "github.com/go-redis/redis/v8" + "github.com/jackc/pgx/v4/pgxpool" base "github.com/streadway/amqp" ) +const ( + SERVICE_USER_AGENT = "order-httpclient" +) + type OrderService struct { - ebCh *base.Channel - log *fluentd.Logger + dbConn *pgxpool.Pool + redis *redis.Client + ebCh *base.Channel + log *fluentd.Logger } -func NewOrderService(chn *base.Channel, log *fluentd.Logger) *OrderService { - return &OrderService{chn, log} +func NewOrderService(dbConn *pgxpool.Pool, redis *redis.Client, chn *base.Channel, log *fluentd.Logger) *OrderService { + return &OrderService{dbConn, redis, chn, log} } +func (s *OrderService) Log(format string, val ...any) { + s.log.Log(format, val...) +} + +// FIXME: REFACTOR !! +func (s *OrderService) CreateOrder(ctx context.Context, basketID string) (*model.OrderModel, error) { + basketAPI := api.NewBasketAPI(SERVICE_USER_AGENT, s.redis) + basket, err := basketAPI.GetBasket(basketID) + if err != nil { + return nil, err + } + + order := new(model.OrderModel) + order.State = basket.State // FIXME: are the same status? + + sql := `INSERT INTO ordering."order"(state) VALUES($1) RETURNING id` + if err := s.dbConn.QueryRow(ctx, sql, order.State).Scan(&order.ID); err != nil { + return nil, err + } + + items, err := basketAPI.GetBasketItems(basket.ID) + if err != nil { + return nil, err + } + + for _, item := range items { + sql := `INSERT INTO ordering.order_item(order_id,product_id,price,quantity) VALUES($1,$2,$3,$4)` + if _, err := s.dbConn.Exec(ctx, sql, order.ID, item.ProductID, item.Price, item.Quantity); err != nil { + return nil, err + } + } + + return order, nil +} func (s *OrderService) UpdateOrderStatus(reqID, orderID, status string) (string, error) { s.log.Log("Update order#%s status to %s", orderID, status) msg := &event.StatusUpdateEvent{Event: event.NewEvent(reqID), OrderID: orderID, Status: status} amqp.Publish(s.ebCh, "api-events", "order.email.statusUpdate", msg) - amqp.Publish(s.ebCh, "api-events", "order.warehouse.orderFinalized", msg) // test event... + // amqp.Publish(s.ebCh, "api-events", "order.warehouse.orderFinalized", msg) // test event... return orderID, nil } diff --git a/src/internal/app/ui/order.go b/src/internal/app/ui/order.go new file mode 100644 index 0000000..e720a6b --- /dev/null +++ b/src/internal/app/ui/order.go @@ -0,0 +1,31 @@ +package ui + +import ( + "context" + + def "git.pbiernat.dev/egommerce/api-entities/http" + "git.pbiernat.dev/egommerce/api-entities/model" + "git.pbiernat.dev/egommerce/order-service/internal/app/service" +) + +// FIXME: REFACTOR !! +func CreateOrder(srv *service.OrderService, basketID, reqID string) (*model.OrderModel, error) { // FIXME: model.Order + ctx := context.Background() + order, err := srv.CreateOrder(ctx, basketID) + if err != nil { + srv.Log("UI CreateOrder error: %v\n", err) + return nil, err + } + + return order, nil +} + +func UpdateOrderStatus(srv *service.OrderService, orderID, status, reqID string) (*def.UpdateOrderStatusResponse, error) { + res := &def.UpdateOrderStatusResponse{} + _, err := srv.UpdateOrderStatus(reqID, orderID, status) + if err != nil { + return res, err + } + + return res, nil +} -- 2.39.5 From 57739506acab3244ef9675acf8861c206d5ffad6 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Mon, 20 Mar 2023 17:42:40 +0100 Subject: [PATCH 12/18] update --- src/internal/app/service/order.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/internal/app/service/order.go b/src/internal/app/service/order.go index 3b65f38..0c11cbb 100644 --- a/src/internal/app/service/order.go +++ b/src/internal/app/service/order.go @@ -32,7 +32,7 @@ func (s *OrderService) Log(format string, val ...any) { s.log.Log(format, val...) } -// FIXME: REFACTOR !! +// Refactor func (s *OrderService) CreateOrder(ctx context.Context, basketID string) (*model.OrderModel, error) { basketAPI := api.NewBasketAPI(SERVICE_USER_AGENT, s.redis) basket, err := basketAPI.GetBasket(basketID) @@ -67,7 +67,6 @@ func (s *OrderService) UpdateOrderStatus(reqID, orderID, status string) (string, msg := &event.StatusUpdateEvent{Event: event.NewEvent(reqID), OrderID: orderID, Status: status} amqp.Publish(s.ebCh, "api-events", "order.email.statusUpdate", msg) - // amqp.Publish(s.ebCh, "api-events", "order.warehouse.orderFinalized", msg) // test event... return orderID, nil } -- 2.39.5 From 8a5b30c0b909e5c90d34b7fb67b39f7cea0a99a4 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Thu, 30 Mar 2023 22:18:33 +0200 Subject: [PATCH 13/18] Added LICENSE --- LICENSE.md | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..d0e1a69 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,173 @@ +# Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International + +Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. + +**Using Creative Commons Public Licenses** + +Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. + +* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). + +* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). + +## Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. + +### Section 1 – Definitions. + +a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. + +b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. + +c. __BY-NC-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License. + +d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. + +f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. + +g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution, NonCommercial, and ShareAlike. + +h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. + +i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. + +j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. + +k. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. + +l. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. + +m. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. + +n. __You__ means the individual or entity exercising the Licensed Rights under this Public License. __Your__ has a corresponding meaning. + +### Section 2 – Scope. + +a. ___License grant.___ + + 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and + + B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only. + + 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. + + 3. __Term.__ The term of this Public License is specified in Section 6(a). + + 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. __Downstream recipients.__ + + A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. + + B. __Additional offer from the Licensor – Adapted Material.__ Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. + + C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. + + 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). + +b. ___Other rights.___ + + 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes. + +### Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + +a. ___Attribution.___ + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + + B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. + + 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. + +b. ___ShareAlike.___ + +In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. + +1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-NC-SA Compatible License. + +2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. + +3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. + +### Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only; + +b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and + +c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. + +### Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ + +b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ + +c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. + +### Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. + +c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. + +d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +### Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. + +### Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. + +b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. + +c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. + +> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. +> +> Creative Commons may be contacted at creativecommons.org -- 2.39.5 From 98007058243b1f614f42176600a9d478943b8ac3 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 19 Jul 2024 21:27:13 +0200 Subject: [PATCH 14/18] Huge refactoring, resolved tight coupling issues --- .env.dist | 19 +- Dockerfile.builder | 4 +- Dockerfile.target | 9 +- Makefile | 3 + bin/entrypoint.sh | 5 +- bin/migrate.sh | 11 +- deploy/image-build.sh | 2 +- deploy/image-push.sh | 8 +- src/app.run | 1 + src/cmd/health/main.go | 39 + src/cmd/migrate/main.go | 70 +- src/cmd/server/main.go | 98 +-- src/cmd/worker/main.go | 212 +----- src/go.mod | 92 ++- src/go.sum | 680 ++++++++++++++++-- src/internal/app/app.go | 81 +++ src/internal/app/config/env.go | 22 - src/internal/app/log.go | 20 - src/internal/app/plugins.go | 139 ++++ src/internal/app/server/config.go | 31 - src/internal/app/server/router.go | 52 -- src/internal/app/server/server.go | 178 ----- src/internal/app/service/order.go | 72 -- src/internal/app/ui/order.go | 31 - src/internal/{app => }/event/email.go | 0 src/internal/{app => }/event/event.go | 4 +- src/internal/{app => }/event/order.go | 0 src/internal/server/config.go | 111 +++ .../{app => }/server/health_handler.go | 4 +- src/internal/server/middleware.go | 32 + .../{app => }/server/order_handler.go | 14 +- src/internal/server/router.go | 27 + src/internal/server/server.go | 136 ++++ src/internal/service/order.go | 93 +++ src/internal/ui/order.go | 37 + src/internal/worker/command.go | 54 ++ src/internal/worker/config.go | 85 +++ src/internal/worker/ext.go | 133 ++++ src/internal/worker/worker.go | 206 ++++++ src/{internal/app => pkg}/database/connect.go | 6 +- 40 files changed, 1998 insertions(+), 823 deletions(-) create mode 100644 src/app.run create mode 100644 src/cmd/health/main.go create mode 100644 src/internal/app/app.go delete mode 100644 src/internal/app/config/env.go delete mode 100644 src/internal/app/log.go create mode 100644 src/internal/app/plugins.go delete mode 100644 src/internal/app/server/config.go delete mode 100644 src/internal/app/server/router.go delete mode 100644 src/internal/app/server/server.go delete mode 100644 src/internal/app/service/order.go delete mode 100644 src/internal/app/ui/order.go rename src/internal/{app => }/event/email.go (100%) rename src/internal/{app => }/event/event.go (55%) rename src/internal/{app => }/event/order.go (100%) create mode 100644 src/internal/server/config.go rename src/internal/{app => }/server/health_handler.go (74%) create mode 100644 src/internal/server/middleware.go rename src/internal/{app => }/server/order_handler.go (55%) create mode 100644 src/internal/server/router.go create mode 100644 src/internal/server/server.go create mode 100644 src/internal/service/order.go create mode 100644 src/internal/ui/order.go create mode 100644 src/internal/worker/command.go create mode 100644 src/internal/worker/config.go create mode 100644 src/internal/worker/ext.go create mode 100644 src/internal/worker/worker.go rename src/{internal/app => pkg}/database/connect.go (54%) diff --git a/.env.dist b/.env.dist index 84c5d45..1b1e7dd 100644 --- a/.env.dist +++ b/.env.dist @@ -1,4 +1,15 @@ -SERVER_ADDR=:80 -DATABASE_URL=postgres://postgres:12345678@postgres-db:5432/egommerce -MONGODB_URL=mongodb://mongodb:12345678@mongo-db:27017 -EVENTBUS_URL=amqp://guest:guest@api-eventbus:5672 \ No newline at end of file +SERVER_ADDR=:1883 + +APP_NAME=order-svc +APP_DOMAIN=host.docker.internal +REGISTRY_USE_DOMAIN_OVER_IP=true +APP_PATH_PREFIX=/order +APP_KV_NAMESPACE=dev.egommerce/service/order-svc + +LOGGER_ADDR=egommerce.local:48400 +REGISTRY_ADDR=egommerce.local:48100 +DATABASE_URL=postgres://postgres:12345678@egommerce.local:48500/egommerce +CACHE_ADDR=egommerce.local:48300 +CACHE_PASSWORD=12345678 +MONGODB_URL=mongodb://mongodb:12345678@egommerce.local:48600 +EVENTBUS_URL=amqp://guest:guest@egommerce.local:48201 diff --git a/Dockerfile.builder b/Dockerfile.builder index 6ccc27d..9524430 100644 --- a/Dockerfile.builder +++ b/Dockerfile.builder @@ -5,6 +5,7 @@ ARG BIN_OUTPUT=/go/bin ARG GO_SERVER=cmd/server/main.go ARG GO_MIGRATE=cmd/migrate/main.go ARG GO_WORKER=cmd/worker/main.go +ARG GO_HEALTH=cmd/health/main.go WORKDIR /go/src/app COPY src ./ @@ -12,4 +13,5 @@ COPY src ./ RUN export CGO_ENABLED=0 ; export GOOS=linux ; export GOARCH=amd64 && \ go build -ldflags="-w -s" -o "$BIN_OUTPUT/server" $GO_SERVER && \ go build -ldflags="-w -s" -o "$BIN_OUTPUT/migrate" $GO_MIGRATE && \ - go build -ldflags="-w -s" -o "$BIN_OUTPUT/worker" $GO_WORKER + go build -ldflags="-w -s" -o "$BIN_OUTPUT/worker" $GO_WORKER && \ + go build -ldflags="-w -s" -o "$BIN_OUTPUT/health" $GO_HEALTH diff --git a/Dockerfile.target b/Dockerfile.target index 944c9ce..a934e6f 100644 --- a/Dockerfile.target +++ b/Dockerfile.target @@ -19,12 +19,17 @@ LABEL dev.egommerce.image.build_time=${BUILD_TIME} WORKDIR / COPY --from=builder $BIN_OUTPUT /app -COPY --from=builder /go/bin/migrate /bin/go_migrate +COPY --from=builder /go/bin/migrate /bin/migrate +COPY --from=builder /go/bin/health /bin/health COPY .env.dist /.env COPY ./bin /bin RUN chmod 755 /bin/entrypoint.sh /bin/migrate.sh +RUN apk add curl + EXPOSE 80 -CMD ["/app"] ENTRYPOINT ["entrypoint.sh"] +CMD ["sh", "-c", "/app"] + +HEALTHCHECK --interval=5s --timeout=1s --retries=20 CMD health >/dev/null || exit 1 diff --git a/Makefile b/Makefile index 2d234f9..86e36c3 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,9 @@ build-image-dev: build-image-prod: - sh ${DEPLOY_DIR}/image-build.sh +push-image-dev: + - sh ${DEPLOY_DIR}/image-push.sh dev + push-image-prod: - sh ${DEPLOY_DIR}/image-push.sh diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 3cea32c..44acbde 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -14,10 +14,13 @@ waitForService() done } +update-resolv # provided by stack - better approach - single copy +update-ca-certificates + +waitForService "api-registry:8500" waitForService "postgres-db:5432" waitForService "api-eventbus:5672" waitForService "api-logger:24224" -waitForService "api-registry:8500" waitForService "basket-svc:80" # run migrations diff --git a/bin/migrate.sh b/bin/migrate.sh index e2980b8..fc1c9b9 100644 --- a/bin/migrate.sh +++ b/bin/migrate.sh @@ -1,17 +1,17 @@ #!/usr/bin/env sh # ensure migrate env is initialized -$(go_migrate version >/dev/null 2>&1) +$(migrate version >/dev/null 2>&1) version=$? if [ $version != "0" ] then echo "Creating base table..." - $(go_migrate init >/dev/null 2>&1) + $(migrate init >/dev/null 2>&1) init=$? fi # check again -$(go_migrate version >/dev/null 2>&1) +$(migrate version >/dev/null 2>&1) version=$? if [ $version != "0" ] then @@ -20,7 +20,6 @@ then fi # run migrations -go_migrate up -echo "Done." +migrate up -exit $version +exit 0 diff --git a/deploy/image-build.sh b/deploy/image-build.sh index ecf2ca2..cb19a5a 100755 --- a/deploy/image-build.sh +++ b/deploy/image-build.sh @@ -1,7 +1,7 @@ #!/bin/sh # RUN IN REPO ROOT DIR !! -export IMAGE_PREFIX="git.pbiernat.dev/egommerce/order" +export IMAGE_PREFIX="git.pbiernat.io/egommerce/order" export BUILDER_IMAGE="egommerce-builder:order" export BUILD_TIME=$(date +"%Y%m%d%H%M%S") export SERVER_IMAGE="$IMAGE_PREFIX-svc" diff --git a/deploy/image-push.sh b/deploy/image-push.sh index bee5bd2..8ae2049 100755 --- a/deploy/image-push.sh +++ b/deploy/image-push.sh @@ -1,13 +1,17 @@ #!/bin/sh # RUN IN REPO ROOT DIR !! -export IMAGE_BASE="git.pbiernat.dev/egommerce/order" +export IMAGE_BASE="git.pbiernat.io/egommerce/order" export SERVER_IMAGE="$IMAGE_BASE-svc" export WORKER_IMAGE="$IMAGE_BASE-worker" TARGET=${1:-latest} -echo $DOCKER_PASSWORD | docker login git.pbiernat.dev -u $DOCKER_USERNAME --password-stdin +echo $DOCKER_PASSWORD | docker login git.pbiernat.io -u $DOCKER_USERNAME --password-stdin docker push "$SERVER_IMAGE:$TARGET" docker push "$WORKER_IMAGE:$TARGET" + +# Restart container +curl -X POST http://127.0.0.1:9001/api/webhooks/c9657d12-22fb-48c4-a7a9-add42f2f71cd +curl -X POST http://127.0.0.1:9001/api/webhooks/9f979396-5cdf-46a2-bf7a-eae07760b04e diff --git a/src/app.run b/src/app.run new file mode 100644 index 0000000..a18c848 --- /dev/null +++ b/src/app.run @@ -0,0 +1 @@ +1698893 \ No newline at end of file diff --git a/src/cmd/health/main.go b/src/cmd/health/main.go new file mode 100644 index 0000000..c27f125 --- /dev/null +++ b/src/cmd/health/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "flag" + "fmt" + "os" +) + +const usageText = `This program runs healthcheck on the app. +Usage: + go run cmd/health/main.go +` + +func init() { + flag.Usage = func() { + fmt.Print(usageText) + flag.PrintDefaults() + os.Exit(2) + } + flag.Parse() +} + +func main() { + var exitCode = 1 + if isOk := healthCheck(); isOk { + exitCode = 0 + } + os.Exit(exitCode) +} + +func healthCheck() bool { + run, err := os.Open("/app.run") + if err != nil { + return false + } + defer run.Close() + + return true +} diff --git a/src/cmd/migrate/main.go b/src/cmd/migrate/main.go index 5eb9e54..7002eac 100644 --- a/src/cmd/migrate/main.go +++ b/src/cmd/migrate/main.go @@ -6,10 +6,13 @@ import ( "log" "os" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - "git.pbiernat.dev/egommerce/order-service/internal/app/config" "github.com/go-pg/migrations/v8" "github.com/go-pg/pg/v10" + + "git.pbiernat.io/egommerce/go-api-pkg/fluentd" + + baseCnf "git.pbiernat.io/egommerce/go-api-pkg/config" + cnf "git.pbiernat.io/egommerce/order-service/internal/server" ) const ( @@ -32,57 +35,56 @@ Usage: ` func main() { - if config.ErrLoadingEnvs != nil { - log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + flag.Usage = func() { + fmt.Print(usageText) + flag.PrintDefaults() + os.Exit(2) + } + flag.Parse() + + if baseCnf.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", baseCnf.ErrLoadingEnvs) } - // dbURL := config.GetEnv("DATABASE_URL", defDbURL) - loggerAddr := config.GetEnv("LOGGER_ADDR", defLoggerAddr) - mTblName := config.GetEnv("MIGRATIONS_TABLE_NAME", defMigrationsTableName) + c := cnf.NewConfig("order-migrator") - logHost, logPort := fluentd.ParseAddr(loggerAddr) - logger := fluentd.NewLogger(defAppName, logHost, logPort) + // dbURL := baseCnf.GetEnv("DATABASE_URL", defDbURL) + + logHost, logPort, err := fluentd.ParseAddr(c.LoggerAddr) + if err != nil { + log.Fatalf("Error parsing logger addr: %s. Err: %v", c.LoggerAddr, err) + } + + logger, err := fluentd.NewLogger(c.Base.GetAppFullName(), logHost, logPort) // @Refactor NewLogger return (logger, error) + if err != nil { + log.Fatalf("Error connecting to %s:%d. Err: %v", logHost, logPort, err) + } defer logger.Close() - flag.Usage = usage - flag.Parse() - db := pg.Connect(&pg.Options{ // FIXME Addr: "postgres-db:5432", User: "postgres", Password: "12345678", Database: "egommerce", }) + defer db.Close() + mTbl := baseCnf.GetEnv("MIGRATIONS_TABLE_NAME", defMigrationsTableName) mig := migrations.NewCollection() - mig.SetTableName(mTblName) - err := mig.DiscoverSQLMigrations("./migrations") - if err != nil { - fmt.Println(err) + mig.SetTableName(mTbl) + if err := mig.DiscoverSQLMigrations("./migrations"); err != nil { + logger.Log("migration dicovery error: %#v", err) } oldVersion, newVersion, err := mig.Run(db, flag.Args()...) if err != nil { - exitf(err.Error()) + logger.Log("migration runner error: %#v", err) + os.Exit(1) } if newVersion != oldVersion { - fmt.Printf("migrated from version %d to %d\n", oldVersion, newVersion) + logger.Log("migrated from version %d to %d\n", oldVersion, newVersion) } else { - fmt.Printf("version is %d\n", oldVersion) + logger.Log("version is %d\n", oldVersion) } -} - -func usage() { - fmt.Print(usageText) - flag.PrintDefaults() - os.Exit(2) -} - -func errorf(s string, args ...interface{}) { - fmt.Fprintf(os.Stderr, s+"\n", args...) -} - -func exitf(s string, args ...interface{}) { - errorf(s, args...) - os.Exit(1) + // os.Exit(0) } diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index 3c35036..8c56272 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -1,97 +1,41 @@ package main import ( + "fmt" "log" "os" - "strconv" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" - "git.pbiernat.dev/egommerce/order-service/internal/app/config" - "git.pbiernat.dev/egommerce/order-service/internal/app/database" - "git.pbiernat.dev/egommerce/order-service/internal/app/server" - "github.com/go-redis/redis/v8" -) + cnf "git.pbiernat.io/egommerce/go-api-pkg/config" -const ( - defAppName = "order-svc" - defAppDomain = "order-svc" - defPathPrefix = "/order" - defNetAddr = ":80" - defLoggerAddr = "api-logger:24224" - defRegistryAddr = "api-registry:8500" - defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" - defCacheAddr = "api-cache:6379" - defCachePassword = "12345678" - defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" - defEventBusURL = "amqp://guest:guest@api-eventbus:5672" - ebEventsExchange = "api-events" - ebEventsQueue = "order-svc" - defKVNmspc = "dev.egommerce/service/order-svc" + "git.pbiernat.io/egommerce/order-service/internal/app" + "git.pbiernat.io/egommerce/order-service/internal/server" ) func main() { - if config.ErrLoadingEnvs != nil { - log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + if cnf.ErrLoadingEnvs != nil { + log.Panicln("Error loading .env file", cnf.ErrLoadingEnvs) } - c := new(server.Config) - c.AppID, _ = os.Hostname() - c.AppName = config.GetEnv("APP_NAME", defAppName) - c.AppDomain = config.GetEnv("APP_DOMAIN", defAppDomain) - c.PathPrefix = config.GetEnv("APP_PATH_PREFIX", defPathPrefix) - c.NetAddr = config.GetEnv("SERVER_ADDR", defNetAddr) - c.Port, _ = strconv.Atoi(c.NetAddr[1:]) - c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) - c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) - c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) - c.CacheAddr = config.GetEnv("CACHE_ADDR", defCacheAddr) - c.CachePassword = config.GetEnv("CACHE_PASSWORD", defCachePassword) - c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) - c.EventBusExchange = ebEventsExchange - c.KVNamespace = config.GetEnv("APP_KV_NAMESPACE", defKVNmspc) + c := server.NewConfig("order") + cArr := c.GetArray() - logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) - logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) - defer logger.Close() + doer := server.New(c) + a := app.NewApp(doer) + a.RegisterPlugin(app.LoggerPlugin(cArr)) + a.RegisterPlugin(app.CachePlugin(cArr)) + a.RegisterPlugin(app.DatabasePlugin(cArr)) + a.RegisterPlugin(app.EventbusPlugin(cArr)) + a.RegisterPlugin(app.RegistryPlugin(cArr)) - // db conn - dbConn, err := database.Connect(c.DbURL) - if err != nil { // fixme: add wait-for-db... - logger.Log("Failed to connect to Database server: %v\n", err) - os.Exit(1) - } - defer dbConn.Close() + while := make(chan struct{}) + err := a.Start(while) + <-while - // redis conn - redis := redis.NewClient(&redis.Options{ - Addr: c.CacheAddr, - Password: c.CachePassword, - DB: 0, - }) - defer redis.Close() - - // eventbus conn - ebConn, ebCh, err := amqp.Open(c.EventBusURL) if err != nil { - logger.Log("Failed to connect to EventBus server: %v\n", err) - os.Exit(1) - } - defer ebCh.Close() - defer amqp.Close(ebConn) - - err = amqp.NewExchange(ebCh, c.EventBusExchange) - if err != nil { - logger.Log("Failed to declare EventBus exchange: %v\n", err) + log.Fatalf("Failed to start server. Reason: %v\n", err) os.Exit(1) } - // start server - srv := server.NewServer(c, logger, dbConn, redis, ebCh) - - forever := make(chan struct{}) - srv.StartWithGracefulShutdown(forever) - <-forever - - // os.Exit(1) + fmt.Println("Gone") + os.Exit(0) } diff --git a/src/cmd/worker/main.go b/src/cmd/worker/main.go index 0d20002..52da8ee 100644 --- a/src/cmd/worker/main.go +++ b/src/cmd/worker/main.go @@ -1,212 +1,40 @@ package main import ( - "bytes" - "encoding/json" - "errors" "fmt" "log" "os" - "os/signal" - "strings" - "syscall" - "time" - discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" - "git.pbiernat.dev/egommerce/order-service/internal/app/config" - "git.pbiernat.dev/egommerce/order-service/internal/app/database" - "git.pbiernat.dev/egommerce/order-service/internal/app/event" - "git.pbiernat.dev/egommerce/order-service/internal/app/server" - "git.pbiernat.dev/egommerce/order-service/internal/app/service" - "git.pbiernat.dev/egommerce/order-service/internal/app/ui" - "github.com/go-redis/redis/v8" - "github.com/streadway/amqp" -) + cnf "git.pbiernat.io/egommerce/go-api-pkg/config" -const ( - defAppName = "order-worker" - defLoggerAddr = "api-logger:24224" - defRegistryAddr = "api-registry:8500" - defDbURL = "postgres://postgres:12345678@postgres-db:5432/egommerce" - defCacheAddr = "api-cache:6379" - defCachePassword = "12345678" - defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" - defEventBusURL = "amqp://guest:guest@api-eventbus:5672" - ebEventsExchange = "api-events" - ebEventsQueue = "order-worker" - defKVNmspc = "dev.egommerce/service/order-worker" + "git.pbiernat.io/egommerce/order-service/internal/app" + "git.pbiernat.io/egommerce/order-service/internal/worker" ) func main() { - if config.ErrLoadingEnvs != nil { - log.Panicln("Error loading .env file", config.ErrLoadingEnvs) + if cnf.ErrLoadingEnvs != nil { + log.Fatalln("Error loading .env file.") } - c := new(server.Config) - c.AppID, _ = os.Hostname() - c.AppName = config.GetEnv("APP_NAME", defAppName) - c.LoggerAddr = config.GetEnv("LOGGER_ADDR", defLoggerAddr) - c.RegistryAddr = config.GetEnv("REGISTRY_ADDR", defRegistryAddr) - c.DbURL = config.GetEnv("DATABASE_URL", defDbURL) - c.CacheAddr = config.GetEnv("CACHE_ADDR", defCacheAddr) - c.CachePassword = config.GetEnv("CACHE_PASSWORD", defCachePassword) - c.EventBusURL = config.GetEnv("EVENTBUS_URL", defEventBusURL) - c.EventBusExchange = ebEventsExchange - c.EventBusQueue = ebEventsQueue - c.KVNamespace = config.GetEnv("APP_KV_NAMESPACE", defKVNmspc) + c := worker.NewConfig("order-worker") + cArr := c.GetArray() - logHost, logPort := fluentd.ParseAddr(c.LoggerAddr) - logger := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) - defer logger.Close() + doer := worker.New(c) + a := app.NewApp(doer) + a.RegisterPlugin(app.LoggerPlugin(cArr)) + a.RegisterPlugin(app.CachePlugin(cArr)) + a.RegisterPlugin(app.DatabasePlugin(cArr)) + a.RegisterPlugin(app.EventbusPlugin(cArr)) + + while := make(chan struct{}) + err := a.Start(while) + <-while - consul, err := discovery.NewService(c.RegistryAddr, c.AppID, c.AppName, c.AppID, "", "", 0) if err != nil { - logger.Log("Error connecting to %s: %v", c.RegistryAddr, err) - } - - go func(consul *discovery.Service) { - interval := time.Second * 3 - ticker := time.NewTicker(interval) - for range ticker.C { - updateKVConfig(consul, c) // FIXME: duplicated in internal/app/server/server.go - } - }(consul) - - // db conn - dbConn, err := database.Connect(c.DbURL) - if err != nil { // fixme: add wait-for-db... - logger.Log("Failed to connect to Database server: %v\n", err) - os.Exit(1) - } - defer dbConn.Close() - - // redis conn - redis := redis.NewClient(&redis.Options{ - Addr: c.CacheAddr, - Password: c.CachePassword, - DB: 0, - }) - defer redis.Close() - - // eventbus conn - ebConn, ebCh, err := rabbitmq.Open(c.EventBusURL) - if err != nil { - logger.Log("Failed to connect to EventBus server: %v\n", err) - os.Exit(1) - } - defer ebCh.Close() - defer rabbitmq.Close(ebConn) - - err = rabbitmq.NewExchange(ebCh, c.EventBusExchange) - if err != nil { - logger.Log("Failed to declare EventBus exchange: %v\n", err) + log.Fatalf("Failed to start worker. Reason: %v\n", err) os.Exit(1) } - // create and bind queues - _, err = ebCh.QueueDeclare( - c.EventBusQueue, // name - false, // durable - false, // delete when unused - false, // exclusive - false, // no-wait - nil, // arguments - ) - if err != nil { - logger.Log("Failed to declare EventBus queue: %v\n", err) - os.Exit(1) - } - - rabbitmq.BindQueueToExchange(ebCh, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") - // if err != nil { - // logger.Log("Failed to prepare EventBus queue: %v\n", err) - // os.Exit(1) - // } - - // event consume - msgs, err := ebCh.Consume( - c.EventBusQueue, // queue - "", // consumer - false, // auto-ack - false, // exclusive - false, // no-local - false, // no-wait - nil, // args - ) - if err != nil { - logger.Log("Failed to register a consumer: %s", err) - os.Exit(1) - } - - forever := make(chan struct{}) - go func() { - sigint := make(chan os.Signal, 1) - signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - <-sigint - - logger.Log("Worker %s stopped working...\n", c.GetAppFullName()) - - close(forever) - }() - - go func() { - orderSrv := service.NewOrderService(dbConn, redis, ebCh, logger) - - for d := range msgs { - go func(d amqp.Delivery) { - msg, err := rabbitmq.Deserialize(d.Body) - if err != nil { - logger.Log("deserialize error: %v\n", err) - d.Reject(false) // FIXME: how to handle erros in queue...???? - return - } - - eName := fmt.Sprintf("%s", msg["event"]) - data := (msg["data"]).(map[string]interface{}) - logger.Log("Message<%s>: %s\n", eName, data) - - reqID := data["request_id"].(string) // FIXME Check input params! - - switch true { - case strings.Contains(eName, event.EVENT_BASKET_CHECKOUT): - basketID := data["basket_id"].(string) // FIXME Check input params! - // create new order based on basket - order, err := ui.CreateOrder(orderSrv, basketID, reqID) - if err != nil { - logger.Log("%s error: %v", event.EVENT_BASKET_CHECKOUT, err) - d.Reject(false) // FIXME: or Nack? how to handle erros in queue... - break - } - logger.Log("Event: %s. Created Order: %v", event.EVENT_BASKET_CHECKOUT, order) - } - - logger.Log("ACK: %s", eName) - d.Ack(false) - }(d) - } - }() - - logger.Log("Waiting for messages...") - <-forever -} - -func updateKVConfig(s *discovery.Service, oldCnf *server.Config) error { // FIXME: duplicated in internal/app/server/server.go - data, _, err := s.KV().Get(oldCnf.KVNamespace, nil) - if err != nil { - return err - } - - if data == nil { - return errors.New("empty KV config data") - } - - buf := bytes.NewBuffer(data.Value) - decoder := json.NewDecoder(buf) - if err := decoder.Decode(oldCnf); err != nil { - return err - } - - return nil + fmt.Println("Gone") + os.Exit(0) } diff --git a/src/go.mod b/src/go.mod index eebbae8..baa7128 100644 --- a/src/go.mod +++ b/src/go.mod @@ -1,53 +1,98 @@ -module git.pbiernat.dev/egommerce/order-service +module git.pbiernat.io/egommerce/order-service go 1.18 require ( - git.pbiernat.dev/egommerce/api-entities v0.0.26 - git.pbiernat.dev/egommerce/go-api-pkg v0.0.136 + git.pbiernat.io/egommerce/api-entities v0.2.3 + git.pbiernat.io/egommerce/go-api-pkg v0.2.88 + github.com/georgysavva/scany/v2 v2.0.0 github.com/go-pg/migrations/v8 v8.1.0 github.com/go-pg/pg/v10 v10.10.7 github.com/go-redis/redis/v8 v8.11.5 github.com/gofiber/fiber/v2 v2.40.1 - github.com/jackc/pgx/v4 v4.17.2 - github.com/joho/godotenv v1.4.0 - github.com/streadway/amqp v1.0.0 + github.com/jackc/pgx/v5 v5.4.1 + github.com/rabbitmq/amqp091-go v1.10.0 ) require ( + github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/aws/aws-sdk-go v1.42.34 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect + github.com/circonus-labs/circonusllhist v0.1.3 // indirect + github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/envoyproxy/go-control-plane v0.11.0 // indirect + github.com/envoyproxy/protoc-gen-validate v0.10.0 // indirect + github.com/fatih/color v1.14.1 // indirect github.com/fluent/fluent-logger-golang v1.9.0 // indirect github.com/go-pg/zerochecker v0.2.0 // indirect - github.com/hashicorp/consul/api v1.18.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/hashicorp/consul v1.16.0 // indirect + github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 // indirect + github.com/hashicorp/consul/api v1.22.0 // indirect + github.com/hashicorp/consul/envoyextensions v0.3.0 // indirect + github.com/hashicorp/consul/sdk v0.14.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-bexpr v0.1.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.3.1 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.6.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-syslog v1.0.0 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/go-version v1.2.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/memberlist v0.5.0 // indirect + github.com/hashicorp/raft v1.5.0 // indirect + github.com/hashicorp/raft-autopilot v0.1.6 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.13.0 // indirect + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.1 // indirect - github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect - github.com/jackc/pgtype v1.13.0 // indirect - github.com/jackc/puddle v1.3.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgtype v1.14.3 // indirect + github.com/jackc/puddle/v2 v2.2.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.41 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.0 // indirect + github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/philhofer/fwd v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.3 // indirect github.com/tinylib/msgp v1.1.6 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.41.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect @@ -55,8 +100,15 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/crypto v0.20.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect mellium.im/sasl v0.2.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index 75a263e..2b583aa 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,65 +1,179 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -git.pbiernat.dev/egommerce/api-entities v0.0.26 h1:Avz02GINwuYWOjw1fmZIJ3QgGEIz3a5vRQZNaxxUQIk= -git.pbiernat.dev/egommerce/api-entities v0.0.26/go.mod h1:+BXvUcr6Cr6QNpJsW8BUfe1vVILdWDADNE0e3u0lNvU= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.135 h1:qOa6MB6d2/lr0t9c3WWP84rf/T57PNYgizTmuNCDws8= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.135/go.mod h1:w2N79aoumjrrcrGPJLkCwxAHtrLd7G4Uj8VOxvPooa0= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.136 h1:SzJRAkqJKdng/3d0V7o/R0yGh7QaZynPBn/P++on9RA= -git.pbiernat.dev/egommerce/go-api-pkg v0.0.136/go.mod h1:w2N79aoumjrrcrGPJLkCwxAHtrLd7G4Uj8VOxvPooa0= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +git.pbiernat.io/egommerce/api-entities v0.2.3 h1:mR6EYfZkAzh4teydb7KXDBWoxwVW3qasnmmH5J3mnas= +git.pbiernat.io/egommerce/api-entities v0.2.3/go.mod h1:INXAG5x4+i+vNwg1NpfPHiDW8nY1kn1K7pgLOtX+/I0= +git.pbiernat.io/egommerce/go-api-pkg v0.2.88 h1:xya/39BnFeha3Oc76ad/ppoQd6AstTGQd87Qszamr1A= +git.pbiernat.io/egommerce/go-api-pkg v0.2.88/go.mod h1:XIy2mmvRNIzQmYIUAcDZafhRPxTQFS2HDmsK7ZQ6980= +github.com/Azure/azure-sdk-for-go v44.0.0+incompatible h1:e82Yv2HNpS0kuyeCrV29OPKvEiqfs2/uJHic3/3iKdg= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM= +github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.0 h1:nSMjYIe24eBYasAIxt859TxyXef/IqoH+8/g4+LmcVs= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.0 h1:Ml+UCrnlKD+cJmSzrZ/RDcDw86NjkRUpnFh7V5JUhzU= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= +github.com/Azure/go-autorest/autorest/validation v0.3.0 h1:3I9AAI63HfcLtphd9g39ruUwRI+Ca+z/f36KHPFRUss= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/NYTimes/gziphandler v1.0.1 h1:iLrQrdwjDd52kHDA5op2UBJFjmOb9g+7scBan4RN8F0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/aws/aws-sdk-go v1.42.34 h1:fqGAiKmCSRY1rEa4G9VqgkKKbNmLKYq5dKmLtQkvYi8= +github.com/aws/aws-sdk-go v1.42.34/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= +github.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLWvQsR9CzAKt2e+EWV2yX9oXQ4= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs= +github.com/coredns/coredns v1.6.6 h1:GFJXHHBiN2YGp4vS1tltNR0AhI1+TXhb79WT1VAS47I= +github.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA= +github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/digitalocean/godo v1.10.0 h1:uW1/FcvZE/hoixnJcnlmIUvTVNdZCLjRLzmDtRi1xXY= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.11.0 h1:jtLewhRR2vMRNnq2ZZUoCjUlgut+Y0+sDDWPOfwOi1o= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e h1:g8euodkL4GdSpVAjfzhssb07KgVmOUqyF4QOmwFumTs= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.10.0 h1:oIfnZFdC0YhpNNEX+SuIqko4cqqVZeN9IGTrhZje83Y= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= github.com/fluent/fluent-logger-golang v1.9.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/georgysavva/scany/v2 v2.0.0 h1:RGXqxDv4row7/FYoK8MRXAZXqoWF/NM+NP0q50k3DKU= +github.com/georgysavva/scany/v2 v2.0.0/go.mod h1:sigOdh+0qb/+aOs3TVhehVT10p8qJL7K/Zhyz8vWo38= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= +github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= +github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= github.com/go-pg/migrations/v8 v8.1.0 h1:bc1wQwFoWRKvLdluXCRFRkeaw9xDU4qJ63uCAagh66w= github.com/go-pg/migrations/v8 v8.1.0/go.mod h1:o+CN1u572XHphEHZyK6tqyg2GDkRvL2bIoLNyGIewus= github.com/go-pg/pg/v10 v10.4.0/go.mod h1:BfgPoQnD2wXNd986RYEHzikqv9iE875PrFaZ9vXvtNM= @@ -72,15 +186,28 @@ github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= -github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -89,63 +216,147 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= -github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= -github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= -github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= +github.com/gophercloud/gophercloud v0.3.0 h1:6sjpKIpVwRIIwmcEGp+WwNovNsem+c+2vm6oxshRpL8= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= +github.com/hashicorp/consul v1.16.0 h1:fMv95ma6OrLjGS81uBhv8TsRdHYmW6VqXDTMUcW8x1w= +github.com/hashicorp/consul v1.16.0/go.mod h1:ASaLvXX8rmh1/VkBN6sr2Dqgtl+RgAg3BqmcB3QGsv8= +github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnveDe20yFa6lSkfdQZm5BR/b271n0MsB5R2L3us= +github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 h1:wzWurXrxfSyG1PHskIZlfuXlTSCj1Tsyatp9DtaasuY= +github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69/go.mod h1:svUZZDvotY8zTODknUePc6mZ9pX8nN0ViGwWcUSOBEA= +github.com/hashicorp/consul/api v1.22.0 h1:ydEvDooB/A0c/xpsBd8GSt7P2/zYPBui4KrNip0xGjE= +github.com/hashicorp/consul/api v1.22.0/go.mod h1:zHpYgZ7TeYqS6zaszjwSt128OwESRpnhU9aGa6ue3Eg= +github.com/hashicorp/consul/envoyextensions v0.3.0 h1:bcLqaRlVy8C01H76AvkHXLnnpHClPCuozEMAZloNkp4= +github.com/hashicorp/consul/envoyextensions v0.3.0/go.mod h1:7Rk3IdYkHhLf7GWiUyOZ18404MfAmSa8zQ2nzNSw6qM= +github.com/hashicorp/consul/proto-public v0.4.0 h1:amEli9TgZBatDzvqW+k9E2HQEfOrIkIAlAreeP7vIlA= +github.com/hashicorp/consul/sdk v0.14.0 h1:Hly+BMNMssVzoWddbBnBFi3W+Fzytvm0haSkihhj3GU= +github.com/hashicorp/consul/sdk v0.14.0/go.mod h1:gHYeuDa0+0qRAD6Wwr6yznMBvBwHKoxSBoW5l73+saE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.2 h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs= +github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= -github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-connlimit v0.3.0 h1:oAojHGjFxUTTTA8c5XXnDqWJ2HLuWbDiBPTpWvNzvqM= +github.com/hashicorp/go-discover v0.0.0-20220714221025-1c234a67149a h1:xeDSq/xo0CfnSZnPUkNH/00Qy8Q8ySJW0Ij2u/pH680= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.0.0 h1:c1fiLq1LNghmLOry1ipGhvLDi+/zEoaEP2JrE1oFJ9s= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo= +github.com/hashicorp/go-raftchunking v0.7.0 h1:APNMnCXmTOhumkFv/GpJIbq7HteWF7EnGZ3875lRN0Y= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= +github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ= +github.com/hashicorp/hcp-sdk-go v0.48.0 h1:LWpFR7YVDz4uG4C/ixcy2tRbg7/BgjMcTh1bRkKaeBQ= +github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w= +github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8= +github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= +github.com/hashicorp/raft-autopilot v0.1.6 h1:C1q3RNF2FfXNZfHWbvVAu0QixaQK8K5pX4O5lh+9z4I= +github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= +github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw= +github.com/hashicorp/raft-wal v0.3.0 h1:Mi6RPoRbsxIIYZryI+bSTXHD97Ua6rIYO51ibYV9bkY= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4= +github.com/hashicorp/vault/api v1.8.3 h1:cHQOLcMhBR+aVI0HzhPxO62w2+gJhIrKguQNONPzu6o= +github.com/hashicorp/vault/api/auth/gcp v0.3.0 h1:taum+3pCmOXnNgEKHlQbmgXmKw5daWHk7YJrLPP/w8g= +github.com/hashicorp/vault/sdk v0.7.0 h1:2pQRO40R1etpKkia5fb4kjrdYMx3BHklPxl1pxpxDHg= +github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -156,16 +367,16 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= -github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= @@ -173,55 +384,73 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= -github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= -github.com/jackc/pgtype v1.13.0 h1:XkIc7A+1BmZD19bB2NxrtjJweHxQ9agqvM+9URc68Cg= -github.com/jackc/pgtype v1.13.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus= +github.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= -github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= +github.com/jackc/pgx/v4 v4.18.2 h1:xVpYkNR5pk5bMCZGfClbO962UIqVABcAGt7ha1s/FeU= +github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/pgx/v5 v5.4.1 h1:oKfB/FhuVtit1bBM3zNRRsZ925ZkMN3HXL+LgLUM9lE= +github.com/jackc/pgx/v5 v5.4.1/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -238,32 +467,53 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= +github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= +github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= @@ -272,55 +522,92 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= +github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= +github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= +github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= -github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -329,12 +616,19 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 h1:8fDzz4GuVg4skjY2B0nMN7h6uN61EDVkuLyI2+qGHhI= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -353,13 +647,36 @@ github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vb github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -372,6 +689,7 @@ golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -383,48 +701,117 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -432,80 +819,219 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210923061019-b8560ed6a9b7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -514,16 +1040,25 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -533,11 +1068,28 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= +k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= +k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/src/internal/app/app.go b/src/internal/app/app.go new file mode 100644 index 0000000..26225c9 --- /dev/null +++ b/src/internal/app/app.go @@ -0,0 +1,81 @@ +package app + +import ( + "log" + "os" + "os/signal" + "strconv" + "syscall" +) + +type ( + Doer interface { + Start() error + RegisterHandler(string, func() any) + OnShutdown() + } + Application interface { + Start(while chan struct{}) + RegisterPlugin(PluginFn) error + Shutdown() + } + + App struct { + doer Doer + } +) + +func NewApp(d Doer) *App { + return &App{ + doer: d, + } +} + +func (a *App) Start(while chan struct{}) error { + go func() { + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + <-sigint + + a.Shutdown() + + close(while) + }() + + run := a.createRunFile("./app.run") // FIXME path... + defer a.removeRunFile(run) + + err := a.doer.Start() + if err != nil { + log.Fatalf("Failed to start app. Reason: %v\n", err) + close(while) + } + <-while + + return err +} + +func (a *App) RegisterPlugin(p Plugin) error { + a.doer.RegisterHandler(p.name, p.fn) + + return nil +} + +func (a *App) Shutdown() { + a.doer.OnShutdown() +} + +func (a *App) createRunFile(path string) *os.File { + run, err := os.Create(path) + if err != nil { + log.Fatalf("Failed to create run file. Reason: %v\n", err) + os.Exit(1) + } + run.WriteString(strconv.Itoa(os.Getpid())) + + return run +} + +func (a *App) removeRunFile(f *os.File) error { + return f.Close() +} diff --git a/src/internal/app/config/env.go b/src/internal/app/config/env.go deleted file mode 100644 index 9dbe349..0000000 --- a/src/internal/app/config/env.go +++ /dev/null @@ -1,22 +0,0 @@ -package config - -import ( - "os" - - "github.com/joho/godotenv" -) - -var ErrLoadingEnvs error - -func init() { - ErrLoadingEnvs = godotenv.Load() -} - -func GetEnv(name string, defVal string) string { // FIXME defVal and return types - env := os.Getenv(name) - if env == "" { - return defVal - } - - return env -} diff --git a/src/internal/app/log.go b/src/internal/app/log.go deleted file mode 100644 index c070f5d..0000000 --- a/src/internal/app/log.go +++ /dev/null @@ -1,20 +0,0 @@ -package app - -import ( - "log" -) - -const AppName = "order-svc" - -func Panic(v ...any) { - log.Panicln(AppName+":", v) -} - -func Panicf(format string, v ...any) { - log.Panicf(AppName+": "+format, v...) -} - -func Panicln(v ...any) { - v = append([]any{AppName + ":"}, v...) - log.Panicln(v...) -} diff --git a/src/internal/app/plugins.go b/src/internal/app/plugins.go new file mode 100644 index 0000000..998d33c --- /dev/null +++ b/src/internal/app/plugins.go @@ -0,0 +1,139 @@ +package app + +import ( + "log" + "os" + "strconv" + + redis "github.com/go-redis/redis/v8" + amqp "github.com/rabbitmq/amqp091-go" + + "git.pbiernat.io/egommerce/go-api-pkg/consul" + "git.pbiernat.io/egommerce/go-api-pkg/fluentd" + + db "git.pbiernat.io/egommerce/order-service/pkg/database" +) + +type ( + Plugin struct { + name string + fn PluginFn + } + PluginFn func() any +) + +func CachePlugin(cArr map[string]string) Plugin { + return Plugin{ + name: "cache", + fn: func() any { + return redis.NewClient(&redis.Options{ + Addr: cArr["cacheAddr"], + Password: cArr["cachePassword"], + DB: 0, + }) + }, + } +} + +func DatabasePlugin(cArr map[string]string) Plugin { + return Plugin{ + name: "database", + fn: func() any { + dbConn, err := db.Connect(cArr["dbURL"]) + if err != nil { + log.Fatalf("Failed to connect to the Database: %s. Err: %v\n", cArr["dbURL"], err) + os.Exit(1) // TODO: retry in background... + } + + return dbConn + }, + } +} + +func EventbusPlugin(cArr map[string]string) Plugin { + return Plugin{ + name: "eventbus", + fn: func() any { + conn, err := amqp.Dial(cArr["eventBusURL"]) + if err != nil { + log.Fatalf("Failed to connect to the EventBus: %s. Err: %v\n", cArr["eventBusURL"], err) + os.Exit(1) // TODO: retry in background... + } + + chn, err := conn.Channel() + if err != nil { + log.Fatalf("Failed to open new EventBus channel. Err: %v\n", err) + os.Exit(1) // TODO: retry in background... + } + + return chn + }, + } +} + +func LoggerPlugin(cArr map[string]string) Plugin { + return Plugin{ + name: "logger", + fn: func() any { + logHost, logPort, err := fluentd.ParseAddr(cArr["loggerAddr"]) + if err != nil { + log.Fatalf("Failed to parse FluentD address: %s. Err: %v", cArr["loggerAddr"], err) + os.Exit(1) // TODO: retry in background... + } + + logger, err := fluentd.NewLogger(cArr["appFullname"], logHost, logPort) + if err != nil { + log.Fatalf("Failed to connect to the FluentD on %s:%d. Err: %v", logHost, logPort, err) + os.Exit(1) // TODO: retry in background... + } + + return logger + }, + } +} + +func RegistryPlugin(cArr map[string]string) Plugin { + return Plugin{ + name: "registry", + fn: func() any { + port, _ := strconv.Atoi(cArr["netAddr"][1:]) // FIXME: can be IP:PORT or :PORT + // log.Printf("Consul retrieved port: %v", port) + registry, err := consul.NewService(cArr["registryAddr"], cArr["id"], cArr["name"], cArr["registryDomainOverIP"], cArr["ip"], cArr["domain"], cArr["pathPrefix"], port) + if err != nil { + log.Fatalf("Failed to connect to the Consul on: %s. Err: %v", cArr["registryAddr"], err) + os.Exit(1) // TODO: retry in background... + } + + err = registry.Register() + if err != nil { + log.Fatalf("Failed to register in the Consul service. Err: %v", err) + os.Exit(1) // TODO: retry in background... + } + + registry.RegisterHealthChecks() + // a.registerKVUpdater() // FIXME run as goroutine + + return registry + + // svc, _ := registry.Connect() + // tlsCnf := svc.ServerTLSConfig() + // s.Base.App.Server().TLSConfig = tlsCnf + // fmt.Println("Podmiana configa TLS") + // defer svc.Close() + + // go func() { // Consul KV updater + // ticker := time.NewTicker(time.Second * 15) + // for range ticker.C { + // fetchKVConfig(s) // FIXME: duplicated in worker + // } + // }() + + // go func() { // Server metadata cache updater + // ticker := time.NewTicker(time.Second * 5) + // for range ticker.C { + // s.cacheMetadata() + // } + // }() + }, + } +} diff --git a/src/internal/app/server/config.go b/src/internal/app/server/config.go deleted file mode 100644 index 5213283..0000000 --- a/src/internal/app/server/config.go +++ /dev/null @@ -1,31 +0,0 @@ -package server - -import "fmt" - -type Config struct { - AppID string - AppName string - AppDomain string - PathPrefix string - NetAddr string - Port int - RegistryAddr string - KVNamespace string - - LoggerAddr string `json:"logger_addr"` - DbURL string `json:"db_url"` - CacheAddr string `json:"cache_addr"` - CachePassword string `json:"cache_password"` - MongoDbUrl string `json:"mongodb_url"` - EventBusURL string `json:"eventbus_url"` - EventBusExchange string `json:"eventbus_exchange"` - EventBusQueue string `json:"eventbus_queue"` - HttpReadTimeout int `json:"http_read_timeout"` - HttpWriteTimeout int `json:"http_write_timeout"` - HttpIdleTimeout int `json:"http_idle_timeout"` - // Fields with json mapping are available trough ConsulKV -} - -func (c *Config) GetAppFullName() string { - return fmt.Sprintf("%s_%s", c.AppName, c.AppID) -} diff --git a/src/internal/app/server/router.go b/src/internal/app/server/router.go deleted file mode 100644 index da4ac45..0000000 --- a/src/internal/app/server/router.go +++ /dev/null @@ -1,52 +0,0 @@ -package server - -import ( - "strings" - - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/cors" -) - -var ( - defaultCORS = cors.New(cors.Config{ - AllowOrigins: "*", - AllowCredentials: true, - AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS", - AllowHeaders: "Accept, Authorization, Content-Type, Vary, X-Request-Id", - }) -) - -func SetupRoutes(s *Server) { - s.App.Options("*", defaultCORS) - - s.App.Get("/health", s.HealthHandler) - s.App.Get("/config", s.ConfigHandler) - - api := s.App.Group("/api") - v1 := api.Group("/v1") - order := v1.Group("/order") - order.Put("/:orderId/status", s.UpdateOrderStatusHandler) -} - -func SetupMiddlewares(s *Server) { - s.App.Use(defaultCORS) - s.App.Use(LoggingMiddleware(s.log)) -} - -// Middlewares -func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { - return func(c *fiber.Ctx) error { - path := string(c.Request().URI().Path()) - if strings.Contains(path, "/health") { - return c.Next() - } - - log.Log("Request: %s, remote: %s, via: %s", - c.Request().URI().String(), - c.Context().RemoteIP().String(), - string(c.Context().UserAgent())) - - return c.Next() - } -} diff --git a/src/internal/app/server/server.go b/src/internal/app/server/server.go deleted file mode 100644 index ea7342d..0000000 --- a/src/internal/app/server/server.go +++ /dev/null @@ -1,178 +0,0 @@ -package server - -import ( - "bytes" - "context" - "encoding/json" - "os" - "os/signal" - "syscall" - "time" - - "github.com/go-redis/redis/v8" - "github.com/gofiber/fiber/v2" - "github.com/jackc/pgx/v4/pgxpool" - "github.com/streadway/amqp" - - def "git.pbiernat.dev/egommerce/api-entities/http" - discovery "git.pbiernat.dev/egommerce/go-api-pkg/consul" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" -) - -type Server struct { - *fiber.App - conf *Config - log *fluentd.Logger - db *pgxpool.Pool - cache *redis.Client - ebCh *amqp.Channel - discovery *discovery.Service - name string - addr string - kvNmspc string -} - -type Headers struct { - RequestID string `reqHeader:"x-request-id"` -} - -func NewServer(conf *Config, logger *fluentd.Logger, db *pgxpool.Pool, cache *redis.Client, ebCh *amqp.Channel) *Server { - consul, err := discovery.NewService(conf.RegistryAddr, conf.AppID, conf.AppName, conf.AppID, conf.AppDomain, conf.PathPrefix, conf.Port) - if err != nil { - logger.Log("Error connecting to %s: %v", conf.RegistryAddr, err) - } - - logger.Log("Registering service with name: %s, address: %s", consul.Name, consul.Address) - err = consul.Register() - if err != nil { - logger.Log("register error: %v", err) - } - - cnf := fiber.Config{ - AppName: conf.AppName, - ServerHeader: conf.AppName, - ReadTimeout: time.Millisecond * 50, - WriteTimeout: time.Millisecond * 50, - IdleTimeout: time.Millisecond * 50, - } - s := &Server{ - fiber.New(cnf), - conf, - logger, - db, - cache, - ebCh, - consul, - conf.AppName, - conf.NetAddr, - conf.KVNamespace, - } - - go func(s *Server) { // Consul KV config updater - interval := time.Second * 15 - ticker := time.NewTicker(interval) - for range ticker.C { - s.updateKVConfig() - } - }(s) - - go func(s *Server) { // Server metadata cache updater - interval := time.Second * 5 - ticker := time.NewTicker(interval) - for range ticker.C { - s.cacheMetadata() - } - }(s) - - SetupMiddlewares(s) - SetupRoutes(s) - - return s -} - -func (s *Server) Start() { - err := s.Listen(s.addr) - s.log.Log("Starting error: %v", err) -} - -func (s *Server) StartWithGracefulShutdown(forever chan struct{}) { - go func() { - sigint := make(chan os.Signal, 1) - signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - <-sigint - - if err := s.gracefulShutdown(); err != nil { - s.log.Log("Server is not shutting down! Reason: %v", err) - } - - close(forever) - }() - - if err := s.Listen(s.addr); err != nil { - s.log.Log("Server is not running! Reason: %v", err) - } - - <-forever -} - -func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { - var hdr = new(Headers) - if err := c.ReqHeaderParser(hdr); err != nil { - return "", err - } - - return hdr.RequestID, nil -} - -func (s *Server) Error400(c *fiber.Ctx, msg string) error { - return c.Status(fiber.StatusBadRequest).JSON(&def.ErrorResponse{Error: msg}) -} - -func (s *Server) Error404(c *fiber.Ctx, msg string) error { - return c.Status(fiber.StatusNotFound).JSON(&def.ErrorResponse{Error: msg}) -} - -func (s *Server) updateKVConfig() { // FIXME: duplicated in cmd/worker/main.go - config, _, err := s.discovery.KV().Get(s.kvNmspc, nil) - if err != nil || config == nil { - return - } - - kvCnf := bytes.NewBuffer(config.Value) - decoder := json.NewDecoder(kvCnf) - if err := decoder.Decode(&s.conf); err != nil { - return - } -} - -func (s *Server) cacheMetadata() { - ctx := context.Background() - key, address := "internal__"+s.conf.AppName+"__ips", s.conf.AppID // FIXME: key name - - pos := s.cache.LPos(ctx, key, address, redis.LPosArgs{}).Val() - if pos >= 0 { - s.cache.LRem(ctx, key, 0, address) - } - - s.cache.LPush(ctx, key, address).Err() -} - -func (s *Server) clearMetadataCache() { - ctx := context.Background() - key, address := "internal__"+s.conf.AppName+"__ips", s.conf.AppID // FIXME: key name - - s.cache.LRem(ctx, key, 0, address) -} - -func (s *Server) gracefulShutdown() error { - s.log.Log("Server is going down...") - s.log.Log("Unregistering service: %s", s.discovery.GetID()) - s.discovery.Unregister() - s.clearMetadataCache() - - s.ebCh.Close() - s.db.Close() - s.log.Close() - - return s.Shutdown() -} diff --git a/src/internal/app/service/order.go b/src/internal/app/service/order.go deleted file mode 100644 index 0c11cbb..0000000 --- a/src/internal/app/service/order.go +++ /dev/null @@ -1,72 +0,0 @@ -package service - -import ( - "context" - - "git.pbiernat.dev/egommerce/api-entities/model" - "git.pbiernat.dev/egommerce/go-api-pkg/api" - "git.pbiernat.dev/egommerce/go-api-pkg/fluentd" - amqp "git.pbiernat.dev/egommerce/go-api-pkg/rabbitmq" - "git.pbiernat.dev/egommerce/order-service/internal/app/event" - "github.com/go-redis/redis/v8" - "github.com/jackc/pgx/v4/pgxpool" - base "github.com/streadway/amqp" -) - -const ( - SERVICE_USER_AGENT = "order-httpclient" -) - -type OrderService struct { - dbConn *pgxpool.Pool - redis *redis.Client - ebCh *base.Channel - log *fluentd.Logger -} - -func NewOrderService(dbConn *pgxpool.Pool, redis *redis.Client, chn *base.Channel, log *fluentd.Logger) *OrderService { - return &OrderService{dbConn, redis, chn, log} -} - -func (s *OrderService) Log(format string, val ...any) { - s.log.Log(format, val...) -} - -// Refactor -func (s *OrderService) CreateOrder(ctx context.Context, basketID string) (*model.OrderModel, error) { - basketAPI := api.NewBasketAPI(SERVICE_USER_AGENT, s.redis) - basket, err := basketAPI.GetBasket(basketID) - if err != nil { - return nil, err - } - - order := new(model.OrderModel) - order.State = basket.State // FIXME: are the same status? - - sql := `INSERT INTO ordering."order"(state) VALUES($1) RETURNING id` - if err := s.dbConn.QueryRow(ctx, sql, order.State).Scan(&order.ID); err != nil { - return nil, err - } - - items, err := basketAPI.GetBasketItems(basket.ID) - if err != nil { - return nil, err - } - - for _, item := range items { - sql := `INSERT INTO ordering.order_item(order_id,product_id,price,quantity) VALUES($1,$2,$3,$4)` - if _, err := s.dbConn.Exec(ctx, sql, order.ID, item.ProductID, item.Price, item.Quantity); err != nil { - return nil, err - } - } - - return order, nil -} -func (s *OrderService) UpdateOrderStatus(reqID, orderID, status string) (string, error) { - s.log.Log("Update order#%s status to %s", orderID, status) - - msg := &event.StatusUpdateEvent{Event: event.NewEvent(reqID), OrderID: orderID, Status: status} - amqp.Publish(s.ebCh, "api-events", "order.email.statusUpdate", msg) - - return orderID, nil -} diff --git a/src/internal/app/ui/order.go b/src/internal/app/ui/order.go deleted file mode 100644 index e720a6b..0000000 --- a/src/internal/app/ui/order.go +++ /dev/null @@ -1,31 +0,0 @@ -package ui - -import ( - "context" - - def "git.pbiernat.dev/egommerce/api-entities/http" - "git.pbiernat.dev/egommerce/api-entities/model" - "git.pbiernat.dev/egommerce/order-service/internal/app/service" -) - -// FIXME: REFACTOR !! -func CreateOrder(srv *service.OrderService, basketID, reqID string) (*model.OrderModel, error) { // FIXME: model.Order - ctx := context.Background() - order, err := srv.CreateOrder(ctx, basketID) - if err != nil { - srv.Log("UI CreateOrder error: %v\n", err) - return nil, err - } - - return order, nil -} - -func UpdateOrderStatus(srv *service.OrderService, orderID, status, reqID string) (*def.UpdateOrderStatusResponse, error) { - res := &def.UpdateOrderStatusResponse{} - _, err := srv.UpdateOrderStatus(reqID, orderID, status) - if err != nil { - return res, err - } - - return res, nil -} diff --git a/src/internal/app/event/email.go b/src/internal/event/email.go similarity index 100% rename from src/internal/app/event/email.go rename to src/internal/event/email.go diff --git a/src/internal/app/event/event.go b/src/internal/event/event.go similarity index 55% rename from src/internal/app/event/event.go rename to src/internal/event/event.go index 3dd7a42..ac529c4 100644 --- a/src/internal/app/event/event.go +++ b/src/internal/event/event.go @@ -1,11 +1,13 @@ package event type Event struct { + Command string `json:"command"` RequestID string `json:"request_id"` } -func NewEvent(reqID string) *Event { +func NewEvent(command, reqID string) *Event { em := new(Event) + em.Command = command em.RequestID = reqID return em diff --git a/src/internal/app/event/order.go b/src/internal/event/order.go similarity index 100% rename from src/internal/app/event/order.go rename to src/internal/event/order.go diff --git a/src/internal/server/config.go b/src/internal/server/config.go new file mode 100644 index 0000000..b94d787 --- /dev/null +++ b/src/internal/server/config.go @@ -0,0 +1,111 @@ +package server + +import ( + "fmt" + "net" + "os" + "time" + + cnf "git.pbiernat.io/egommerce/go-api-pkg/config" +) + +const ( + defName = "order-svc" + defDomain = "order-svc" + defCacheAddr = "egommerce.local:6379" + defCachePassword = "12345678" + defDbURL = "postgres://postgres:12345678@db-postgres:5432/egommerce" + defEventBusURL = "amqp://guest:guest@api-eventbus:5672" + defKVNmspc = "dev.egommerce/service/order" + defLoggerAddr = "api-logger:24224" + defNetAddr = ":80" + defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" + defPathPrefix = "/order" + defRegistryAddr = "api-registry:8500" + defEbEventsExchange = "api-events" + defEbEventsQueue = "order-svc" +) + +type Config struct { + ID string + Name string + Domain string + NetAddr string + RegistryDomainOverIP string + PathPrefix string + + IdleTimeout time.Duration // miliseconds + ReadTimeout time.Duration // miliseconds + WriteTimeout time.Duration // miliseconds + + LoggerAddr string `json:"logger_addr"` + DbURL string `json:"db_url"` + CacheAddr string `json:"cache_addr"` + CachePassword string `json:"cache_password"` + MongoDbUrl string `json:"mongodb_url"` + EventBusURL string `json:"eventbus_url"` + EventBusExchange string `json:"eventbus_exchange"` + EventBusQueue string `json:"eventbus_queue"` + KVNamespace string + RegistryAddr string + + // Fields with JSON mappings are available through Consul KV storage +} + +func NewConfig(name string) *Config { + c := new(Config) + + c.ID, _ = os.Hostname() + c.Name = name + c.Domain = cnf.GetEnv("APP_DOMAIN", defDomain) + c.NetAddr = cnf.GetEnv("SERVER_ADDR", defNetAddr) + c.RegistryDomainOverIP = cnf.GetEnv("REGISTRY_USE_DOMAIN_OVER_IP", "false") + c.PathPrefix = cnf.GetEnv("APP_PATH_PREFIX", defPathPrefix) + + c.CacheAddr = cnf.GetEnv("CACHE_ADDR", defCacheAddr) + c.CachePassword = cnf.GetEnv("CACHE_PASSWORD", defCachePassword) + c.DbURL = cnf.GetEnv("DATABASE_URL", defDbURL) + c.EventBusExchange = defEbEventsExchange + c.EventBusURL = cnf.GetEnv("EVENTBUS_URL", defEventBusURL) + c.KVNamespace = cnf.GetEnv("APP_KV_NAMESPACE", defKVNmspc) + c.LoggerAddr = cnf.GetEnv("LOGGER_ADDR", defLoggerAddr) + c.RegistryAddr = cnf.GetEnv("REGISTRY_ADDR", defRegistryAddr) + + return c +} + +func (c *Config) GetAppFullName() string { + return fmt.Sprintf("%s_%s", c.Name, c.ID) +} + +func (c *Config) GetIP() string { + host, _ := os.Hostname() + ips, _ := net.LookupIP(host) + // for _, ip := range ips { + // return ip.String() + // } + + return ips[0].String() +} + +func (c *Config) GetArray() map[string]string { // FIXME fix types etc + arr := make(map[string]string) + arr["id"] = c.ID + arr["name"] = c.Name + arr["appFullname"] = c.GetAppFullName() + arr["domain"] = c.Domain + arr["ip"] = c.GetIP() + arr["netAddr"] = c.NetAddr + arr["registryDomainOverIP"] = c.RegistryDomainOverIP + arr["pathPrefix"] = c.PathPrefix + arr["cacheAddr"] = c.CacheAddr + arr["cachePassword"] = c.CachePassword + arr["dbURL"] = c.DbURL + arr["eventBusExchange"] = c.EventBusExchange + arr["eventBusURL"] = c.EventBusURL + arr["kvNamespace"] = c.KVNamespace + arr["loggerAddr"] = c.LoggerAddr + arr["registryAddr"] = c.RegistryAddr + + return arr +} diff --git a/src/internal/app/server/health_handler.go b/src/internal/server/health_handler.go similarity index 74% rename from src/internal/app/server/health_handler.go rename to src/internal/server/health_handler.go index 73d756e..6b9c93a 100644 --- a/src/internal/app/server/health_handler.go +++ b/src/internal/server/health_handler.go @@ -3,7 +3,7 @@ package server import ( "github.com/gofiber/fiber/v2" - def "git.pbiernat.dev/egommerce/api-entities/http" + def "git.pbiernat.io/egommerce/api-entities/http" ) func (s *Server) HealthHandler(c *fiber.Ctx) error { @@ -13,5 +13,5 @@ func (s *Server) HealthHandler(c *fiber.Ctx) error { } func (s *Server) ConfigHandler(c *fiber.Ctx) error { - return c.JSON(s.conf) + return c.JSON(s.Config) } diff --git a/src/internal/server/middleware.go b/src/internal/server/middleware.go new file mode 100644 index 0000000..32328d9 --- /dev/null +++ b/src/internal/server/middleware.go @@ -0,0 +1,32 @@ +package server + +import ( + "strings" + + "github.com/gofiber/fiber/v2" + + "git.pbiernat.io/egommerce/go-api-pkg/fluentd" +) + +// "github.com/gofiber/fiber/v2" +// "github.com/gofiber/fiber/v2/middleware/cors" + +func SetupMiddleware(s *Server) { + s.Use(LoggingMiddleware(s.GetLogger())) +} + +func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { + return func(c *fiber.Ctx) error { + path := string(c.Request().URI().Path()) + if strings.Contains(path, "/health") { + return c.Next() + } + + log.Log("Request: %s, remote: %s, via: %s", + c.Request().URI().String(), + c.Context().RemoteIP().String(), + string(c.Context().UserAgent())) + + return c.Next() + } +} diff --git a/src/internal/app/server/order_handler.go b/src/internal/server/order_handler.go similarity index 55% rename from src/internal/app/server/order_handler.go rename to src/internal/server/order_handler.go index 4b14e28..765178b 100644 --- a/src/internal/app/server/order_handler.go +++ b/src/internal/server/order_handler.go @@ -5,28 +5,28 @@ import ( "github.com/gofiber/fiber/v2" - def "git.pbiernat.dev/egommerce/api-entities/http" - "git.pbiernat.dev/egommerce/order-service/internal/app/service" - "git.pbiernat.dev/egommerce/order-service/internal/app/ui" + def "git.pbiernat.io/egommerce/api-entities/http" + "git.pbiernat.io/egommerce/order-service/internal/service" + "git.pbiernat.io/egommerce/order-service/internal/ui" ) func (s *Server) UpdateOrderStatusHandler(c *fiber.Ctx) error { reqID, _ := s.GetRequestID(c) req := new(def.UpdateOrderStatusRequest) if err := c.BodyParser(req); err != nil { - return s.Error400(c, err.Error()) + return s.Error(c, 400, err.Error()) } // check if order exists in DB service... orderID := c.Params("orderId", "") if orderID == "" { - return s.Error400(c, "") + return s.Error(c, 400, "Empty orderId") } - orderSrv := service.NewOrderService(s.db, s.cache, s.ebCh, s.log) + orderSrv := service.NewOrderService(s.GetDatabase(), s.GetCache(), s.GetEventBus(), s.GetLogger()) _, err := ui.UpdateOrderStatus(orderSrv, req.Status, orderID, reqID) if err != nil { - return s.Error400(c, "Failed to update order status") + return s.Error(c, 400, "Failed to update order status") } return c.SendStatus(http.StatusNoContent) diff --git a/src/internal/server/router.go b/src/internal/server/router.go new file mode 100644 index 0000000..a067410 --- /dev/null +++ b/src/internal/server/router.go @@ -0,0 +1,27 @@ +package server + +import ( + "github.com/gofiber/fiber/v2/middleware/cors" +) + +var ( + defaultCORS = cors.New(cors.Config{ + AllowOrigins: "*", + // AllowCredentials: true, + AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS", + AllowHeaders: "Accept, Authorization, Content-Type, Vary, X-Request-Id", + }) +) + +func SetupRouter(s *Server) { + s.Options("*", defaultCORS) + s.Use(defaultCORS) + + s.Get("/health", s.HealthHandler) + s.Get("/config", s.ConfigHandler) + + api := s.Group("/api") + v1 := api.Group("/v1") + order := v1.Group("/order") + order.Put("/:orderId/status", s.UpdateOrderStatusHandler) +} diff --git a/src/internal/server/server.go b/src/internal/server/server.go new file mode 100644 index 0000000..6799c72 --- /dev/null +++ b/src/internal/server/server.go @@ -0,0 +1,136 @@ +package server + +import ( + "net" + "time" + + "github.com/go-redis/redis/v8" + "github.com/gofiber/fiber/v2" + "github.com/jackc/pgx/v5/pgxpool" + amqp "github.com/rabbitmq/amqp091-go" + + "git.pbiernat.io/egommerce/api-entities/http" + "git.pbiernat.io/egommerce/go-api-pkg/consul" + "git.pbiernat.io/egommerce/go-api-pkg/fluentd" +) + +type ( + Server struct { + *fiber.App + + ID string + addr string // e.g. "127.0.0.1:80" + handlers map[string]any + } + HeaderRequestID struct { + RequestID string `reqHeader:"x-request-id"` + } +) + +func New(c *Config) *Server { + return &Server{ + ID: c.ID, + App: fiber.New(fiber.Config{ + AppName: c.ID, + ServerHeader: c.Name + ":" + c.ID, + ReadTimeout: c.ReadTimeout * time.Millisecond, + WriteTimeout: c.WriteTimeout * time.Millisecond, + IdleTimeout: c.IdleTimeout * time.Millisecond, + }), + addr: c.NetAddr, + handlers: make(map[string]any), + } +} + +func (s *Server) Start() error { + SetupMiddleware(s) + SetupRouter(s) + + // fmt.Printf("Starting server at: %s...\n", s.addr) + ln, _ := net.Listen("tcp", s.addr) + // ln = tls.NewListener(ln, s.App.Server().TLSConfig) + + return s.Listener(ln) +} + +func (s *Server) RegisterHandler(name string, fn func() any) { + // fmt.Printf("Registering plugin( with handler): %s... OK\n", name) + s.handlers[name] = fn() +} + +func (s *Server) OnShutdown() { + // s.GetLogger().Log("Server %s is going down...", s.ID) + + s.GetRegistry().Unregister() + // a.clearMetadataCache() + s.GetEventBus().Close() + s.GetDatabase().Close() + s.GetLogger().Log("Gone.") + s.GetLogger().Close() + + s.Shutdown() +} + +func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { + var hdr = new(HeaderRequestID) + if err := c.ReqHeaderParser(hdr); err != nil { + return "", err + } + + return hdr.RequestID, nil +} + +func (s *Server) Error(c *fiber.Ctx, code int, msg string) error { + return c.Status(code).JSON(http.ErrorResponse{Error: msg}) +} + +// Plugin helper funcitons +func (s *Server) GetCache() *redis.Client { + return (s.handlers["cache"]).(*redis.Client) +} + +func (s *Server) GetDatabase() *pgxpool.Pool { // FIXME hardcoded index issue + return (s.handlers["database"]).(*pgxpool.Pool) +} + +func (s *Server) GetEventBus() *amqp.Channel { + return (s.handlers["eventbus"]).(*amqp.Channel) +} + +func (s *Server) GetLogger() *fluentd.Logger { + return (s.handlers["logger"]).(*fluentd.Logger) +} + +func (s *Server) GetRegistry() *consul.Service { + return (s.handlers["registry"]).(*consul.Service) +} + +// @CHECK: merge s.Config and s.Base.Config to display all config as one array/map +// func (s *Server) registerKVUpdater() { // @FIXME: merge duplication in server.go and worker.go +// go func() { +// ticker := time.NewTicker(time.Second * 10) +// for range ticker.C { +// config, _, err := s.Registry.KV().Get(s.Config.KVNamespace, nil) +// if err != nil || config == nil { +// return +// } + +// kvCnf := bytes.NewBuffer(config.Value) +// decoder := json.NewDecoder(kvCnf) +// if err := decoder.Decode(&s.Config); err != nil { +// return +// } +// } +// }() +// } + +// func (s *Server) clearMetadataCache() { +// ctx := context.Background() +// key, address := s.getMetadataIPsKey(), s.Config.Base.AppID + +// s.Cache.LRem(ctx, key, 0, address) +// } + +// func (s *Server) getMetadataIPsKey() string { +// return "internal__" + s.Base.Config.AppName + "__ips" +// } diff --git a/src/internal/service/order.go b/src/internal/service/order.go new file mode 100644 index 0000000..105c682 --- /dev/null +++ b/src/internal/service/order.go @@ -0,0 +1,93 @@ +package service + +import ( + "context" + + "git.pbiernat.io/egommerce/api-entities/model" + "git.pbiernat.io/egommerce/order-service/internal/event" + + "git.pbiernat.io/egommerce/go-api-pkg/api" + "git.pbiernat.io/egommerce/go-api-pkg/fluentd" + "git.pbiernat.io/egommerce/go-api-pkg/rabbitmq" + + "github.com/georgysavva/scany/v2/pgxscan" + "github.com/go-redis/redis/v8" + "github.com/jackc/pgx/v5/pgxpool" + amqp "github.com/rabbitmq/amqp091-go" +) + +const ( + SERVICE_USER_AGENT = "order-httpclient" +) + +type OrderService struct { + dbConn *pgxpool.Pool + redis *redis.Client + ebCh *amqp.Channel + log *fluentd.Logger +} + +func NewOrderService(dbConn *pgxpool.Pool, redis *redis.Client, chn *amqp.Channel, log *fluentd.Logger) *OrderService { + return &OrderService{dbConn, redis, chn, log} +} + +func (s *OrderService) Log(format string, val ...any) { + s.log.Log(format, val...) +} + +func (s *OrderService) GetOrder(ctx context.Context, id string) (*model.OrderModel, error) { + order := new(model.OrderModel) + err := pgxscan.Get(ctx, s.dbConn, order, `SELECT id, state, created_at, updated_at FROM ordering."order" WHERE id=$1`, id) + if err != nil { + return nil, err + } + + return order, nil +} + +func (s *OrderService) CreateOrder(ctx context.Context, basketID string) (*model.OrderModel, error) { + basketAPI := api.NewBasketAPI(SERVICE_USER_AGENT, s.redis) + basket, err := basketAPI.GetBasket(basketID) + if err != nil { + return nil, err + } + + order := new(model.OrderModel) + order.ID = basketID + order.State = basket.State // FIXME: are the same status? + + sql := `INSERT INTO "ordering"."order"(id,state) VALUES($1,$2) RETURNING id` + if err := s.dbConn.QueryRow(ctx, sql, order.ID, order.State).Scan(&order.ID); err != nil { + return order, err + } + + items, err := basketAPI.GetBasketItems(basket.ID) + if err != nil { + return order, err + } + + for _, item := range items { + sql := `INSERT INTO ordering.order_item(order_id,product_id,price,quantity) VALUES($1,$2,$3,$4)` + if _, err := s.dbConn.Exec(ctx, sql, order.ID, item.ProductID, item.Price, item.Quantity); err != nil { + return order, err + } + } + + return order, nil +} + +// func (s *OrderService) UpdateOrder(ctx context.Context, orderID string, data any) (*model.OrderModel, error) { +// } + +func (s *OrderService) UpdateOrderStatus(reqID, orderID, status string) (string, error) { + s.log.Log("Update order#%s status to %s", orderID, status) + + msg := &event.StatusUpdateEvent{ + Event: event.NewEvent("UpdateOrderStatus", reqID), + OrderID: orderID, + Status: status, + } + rabbitmq.Publish(s.ebCh, "api-events", "order.email.statusUpdate", msg) + + return orderID, nil +} diff --git a/src/internal/ui/order.go b/src/internal/ui/order.go new file mode 100644 index 0000000..46144de --- /dev/null +++ b/src/internal/ui/order.go @@ -0,0 +1,37 @@ +package ui + +import ( + "context" + "fmt" + + def "git.pbiernat.io/egommerce/api-entities/http" + "git.pbiernat.io/egommerce/api-entities/model" + "git.pbiernat.io/egommerce/order-service/internal/service" +) + +func CreateOrder(srv *service.OrderService, orderID, reqID string) (*model.OrderModel, error) { // FIXME: model.Order + ctx := context.Background() + order, _ := srv.GetOrder(ctx, orderID) + if order != nil { + srv.Log("order#%s already exists. %v", order.ID, order) + return nil, fmt.Errorf("order#%s already exists", order.ID) + } + + order, err := srv.CreateOrder(ctx, orderID) + if err != nil { + srv.Log("Failed to create an Order: %s. :: %v\n", err, order) + return nil, err + } + + return order, nil +} + +func UpdateOrderStatus(srv *service.OrderService, orderID, status, reqID string) (*def.UpdateOrderStatusResponse, error) { + res := &def.UpdateOrderStatusResponse{} + _, err := srv.UpdateOrderStatus(reqID, orderID, status) + if err != nil { + return res, err + } + + return res, nil +} diff --git a/src/internal/worker/command.go b/src/internal/worker/command.go new file mode 100644 index 0000000..e7d41cf --- /dev/null +++ b/src/internal/worker/command.go @@ -0,0 +1,54 @@ +package worker + +import ( + "git.pbiernat.io/egommerce/order-service/internal/service" +) + +var ( + CheckoutBasket = "event.CheckoutBasket" +) + +type Command interface { + run(CommandData) (bool, any) +} + +type CommandData map[string]interface{} + +type CommandRunner struct { + cmd Command +} + +func NewCommandRunner(data map[string]interface{}, srvc *service.OrderService) *CommandRunner { + rnr := &CommandRunner{} + rnr.cmd = getCommand((data["command"]).(string), srvc) + + return rnr +} + +func getCommand(cmd string, srvc *service.OrderService) Command { + // fmt.Printf("getCommand: %v\n", cmd) + var c Command + + switch cmd { // FIXME + case "CheckoutBasket": + c = &CheckoutBasketCommand{srvc} + } + + return c +} + +func (r *CommandRunner) run(data CommandData) (bool, any) { + return r.cmd.run(data) +} + +type CheckoutBasketCommand struct { + srvc *service.OrderService // FIXME: Remove service dep +} + +func (c *CheckoutBasketCommand) run(data CommandData) (bool, any) { // FIXME: Move run func to WorkerPool + // reqID := data["request_id"].(string) // FIXME Check input params! + // basketID := data["basket_id"].(string) // FIXME Check input params! + + // order, err := ui.CreateOrder(c.srvc, basketID, reqID) + return true, nil //err == nil, basket +} diff --git a/src/internal/worker/config.go b/src/internal/worker/config.go new file mode 100644 index 0000000..8120d18 --- /dev/null +++ b/src/internal/worker/config.go @@ -0,0 +1,85 @@ +package worker + +import ( + "fmt" + "net" + "os" + + cnf "git.pbiernat.io/egommerce/go-api-pkg/config" +) + +const ( + defName = "order-worker" + defDomain = "order-worker" + defCacheAddr = "egommerce.local:6379" + defCachePassword = "12345678" + defDbURL = "postgres://postgres:12345678@db-postgres:5432/egommerce" + defEventBusURL = "amqp://guest:guest@api-eventbus:5672" + defKVNmspc = "dev.egommerce/service/order-worker" + defLoggerAddr = "api-logger:24224" + defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" + defEbEventsExchange = "api-events" + defEbEventsQueue = "order-svc" +) + +type Config struct { + ID string + Name string + + LoggerAddr string `json:"logger_addr"` + DbURL string `json:"db_url"` + CacheAddr string `json:"cache_addr"` + CachePassword string `json:"cache_password"` + MongoDbUrl string `json:"mongodb_url"` + EventBusURL string `json:"eventbus_url"` + EventBusExchange string `json:"eventbus_exchange"` + EventBusQueue string `json:"eventbus_queue"` + KVNamespace string +} + +func NewConfig(name string) *Config { + c := new(Config) + + c.ID, _ = os.Hostname() + c.Name = name + + c.CacheAddr = cnf.GetEnv("CACHE_ADDR", defCacheAddr) + c.CachePassword = cnf.GetEnv("CACHE_PASSWORD", defCachePassword) + c.DbURL = cnf.GetEnv("DATABASE_URL", defDbURL) + c.EventBusExchange = defEbEventsExchange + c.EventBusURL = cnf.GetEnv("EVENTBUS_URL", defEventBusURL) + c.KVNamespace = cnf.GetEnv("APP_KV_NAMESPACE", defKVNmspc) + c.LoggerAddr = cnf.GetEnv("LOGGER_ADDR", defLoggerAddr) + + return c +} + +func (c *Config) GetAppFullName() string { + return fmt.Sprintf("%s_%s", c.Name, c.ID) +} + +func (c *Config) GetIP() string { + host, _ := os.Hostname() + ips, _ := net.LookupIP(host) + // for _, ip := range ips { + // return ip.String() + // } + + return ips[0].String() +} + +func (c *Config) GetArray() map[string]string { // FIXME fix types etc + arr := make(map[string]string) + arr["id"] = c.ID + arr["name"] = c.Name + arr["appFullname"] = c.GetAppFullName() + arr["cacheAddr"] = c.CacheAddr + arr["cachePassword"] = c.CachePassword + arr["dbURL"] = c.DbURL + arr["eventBusExchange"] = c.EventBusExchange + arr["eventBusURL"] = c.EventBusURL + arr["kvNamespace"] = c.KVNamespace + arr["loggerAddr"] = c.LoggerAddr + + return arr +} diff --git a/src/internal/worker/ext.go b/src/internal/worker/ext.go new file mode 100644 index 0000000..e71faff --- /dev/null +++ b/src/internal/worker/ext.go @@ -0,0 +1,133 @@ +package worker + +// import ( +// "bytes" +// "encoding/json" +// "os" +// "time" + +// "git.pbiernat.io/egommerce/go-api-pkg/consul" +// "git.pbiernat.io/egommerce/go-api-pkg/fluentd" +// "git.pbiernat.io/egommerce/go-api-pkg/rabbitmq" +// cnf "git.pbiernat.io/egommerce/order-service/internal/config" +// "git.pbiernat.io/egommerce/order-service/pkg/database" +// "github.com/go-redis/redis/v8" +// ) + +// func WithCache(c *cnf.Config) OptionFn { +// return func(w *Worker) error { +// conn := redis.NewClient(&redis.Options{ +// Addr: c.CacheAddr, +// Password: c.CachePassword, +// DB: 0, +// }) + +// w.Cache = conn + +// return nil +// } +// } + +// func WithDatabase(c *cnf.Config) OptionFn { +// return func(w *Worker) error { +// conn, err := database.Connect(c.DbURL) +// if err != nil { +// w.Logger.Log("Failed to connect to Database server: %v\n", err) +// os.Exit(1) +// } + +// w.Database = conn + +// return nil +// } +// } + +// func WithEventbus(c *cnf.Config) OptionFn { +// return func(w *Worker) error { +// _, chn, err := rabbitmq.Open(c.EventBusURL) +// if err != nil { +// w.Logger.Log("Failed to connect to EventBus server: %v\n", err) +// os.Exit(1) +// } + +// err = rabbitmq.NewExchange(chn, c.EventBusExchange) +// if err != nil { +// w.Logger.Log("Failed to declare EventBus exchange: %v\n", err) +// os.Exit(1) +// } + +// _, err = chn.QueueDeclare( +// c.EventBusQueue, // name +// false, // durable +// false, // delete when unused +// false, // exclusive +// false, // no-wait +// nil, // arguments +// ) +// if err != nil { +// w.Logger.Log("Failed to declare EventBus queue: %v\n", err) +// os.Exit(1) +// } + +// // w.bindQueues() +// rabbitmq.BindQueueToExchange(chn, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") + +// w.Eventbus = chn + +// return nil +// } +// } + +// func WithLogger(c *cnf.Config) OptionFn { +// return func(w *Worker) error { +// logHost, logPort, err := fluentd.ParseAddr(c.LoggerAddr) +// if err != nil { +// w.Logger.Log("Failed to parse Fluentd address: %s. Err: %v", c.LoggerAddr, err) +// os.Exit(1) +// } + +// logger, err := fluentd.NewLogger(c.Base.GetAppFullName(), logHost, logPort) +// if err != nil { +// w.Logger.Log("Failed to connect to the Fluentd on %s:%d. Err: %v", logHost, logPort, err) +// os.Exit(1) +// } + +// w.Logger = logger + +// return nil +// } +// } + +// func WithRegistry(c *cnf.Config) OptionFn { +// return func(w *Worker) error { +// registry, err := consul.NewService(c.RegistryAddr, c.Base.AppID, c.Base.AppName, c.Base.AppID, "", "", 0) +// if err != nil { +// w.Logger.Log("Error connecting to %s: %v", c.RegistryAddr, err) +// } + +// w.Registry = registry + +// go func(w *Worker) { // Fetch Consul KV config and store it in app config +// ticker := time.NewTicker(time.Second * 15) +// for range ticker.C { +// fetchKVConfig(w) // FIXME: duplicated in server +// } +// }(w) + +// return nil +// } + +// } + +// func fetchKVConfig(w *Worker) { // @FIXME: merge duplication in server.go and worker.go +// config, _, err := w.Registry.KV().Get(w.Config.KVNamespace, nil) +// if err != nil || config == nil { +// return +// } + +// kvCnf := bytes.NewBuffer(config.Value) +// decoder := json.NewDecoder(kvCnf) +// if err := decoder.Decode(&w.Config); err != nil { +// return +// } +// } diff --git a/src/internal/worker/worker.go b/src/internal/worker/worker.go new file mode 100644 index 0000000..e70b51f --- /dev/null +++ b/src/internal/worker/worker.go @@ -0,0 +1,206 @@ +package worker + +import ( + "fmt" + "log" + "os" + "strings" + + "github.com/go-redis/redis/v8" + "github.com/jackc/pgx/v5/pgxpool" + amqp "github.com/rabbitmq/amqp091-go" + + "git.pbiernat.io/egommerce/go-api-pkg/fluentd" + "git.pbiernat.io/egommerce/go-api-pkg/rabbitmq" + + "git.pbiernat.io/egommerce/order-service/internal/event" + "git.pbiernat.io/egommerce/order-service/internal/service" +) + +type ( + Worker struct { + ID string + cnf *Config + handlers map[string]any + services map[string]any + doWrkUntil chan struct{} + } +) + +func New(c *Config) *Worker { + return &Worker{ + ID: c.ID, + cnf: c, + handlers: make(map[string]any), + services: make(map[string]any), + doWrkUntil: make(chan struct{}), + } +} + +func (w *Worker) Start() error { + // Init + err := rabbitmq.NewExchange(w.GetEventBus(), w.cnf.EventBusExchange) + if err != nil { + w.GetLogger().Log("Failed to declare EventBus exchange: %v\n", err) + fmt.Printf("Failed to declare EventBus exchange: %v\n", err) + + os.Exit(1) + } + + _, err = w.GetEventBus().QueueDeclare( + w.cnf.EventBusQueue, // name + false, // durable + false, // delete when unused + false, // exclusive + false, // no-wait + nil, // arguments + ) + if err != nil { + w.GetLogger().Log("Failed to declare EventBus queue: %v\n", err) + fmt.Printf("Failed to declare EventBus queue: %v\n", err) + + os.Exit(1) + } + + // // w.bindQueues() + rabbitmq.BindQueueToExchange(w.GetEventBus(), w.cnf.EventBusQueue, w.cnf.EventBusExchange, "basket.order.basketCheckout") + + err = w.doWork(w.doWrkUntil) + if err != nil { + log.Fatalf("Failed to start worker: %s. Reason: %v\n", w.ID, err) + close(w.doWrkUntil) + } + <-w.doWrkUntil + + return err + + // go func() { + // sigint := make(chan os.Signal, 1) + // signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + // <-sigint + + // w.Shutdown() + // close(while) + // }() + + // run := w.createRunFile("./app.run") // TODO move to common library (shared between server and worker) + // defer w.removeRunFile(run) + + // w.Logger.Log("Waiting for messages...") + + // return nil +} + +func (w *Worker) RegisterHandler(name string, fn func() any) { + // fmt.Printf("Registering plugin( with handler): %s... OK\n", name) + w.handlers[name] = fn() +} + +func (w *Worker) OnShutdown() { + w.GetLogger().Log("Worker %s is going down...", w.ID) + // fmt.Printf("Worker %s is going down...\n", w.ID) + w.GetEventBus().Close() + w.GetDatabase().Close() + w.GetLogger().Log("Gone.") + w.GetLogger().Close() + + close(w.doWrkUntil) +} + +// Plugin helper funcitons +func (w *Worker) GetCache() *redis.Client { + return (w.handlers["cache"]).(*redis.Client) +} + +func (w *Worker) GetDatabase() *pgxpool.Pool { // FIXME hardcoded index issue + return (w.handlers["database"]).(*pgxpool.Pool) +} + +func (w *Worker) GetEventBus() *amqp.Channel { + return (w.handlers["eventbus"]).(*amqp.Channel) +} + +func (w *Worker) GetLogger() *fluentd.Logger { + return (w.handlers["logger"]).(*fluentd.Logger) +} + +func (w *Worker) doWork(while chan struct{}) error { + w.services["order"] = + service.NewOrderService(w.GetDatabase(), w.GetCache(), w.GetEventBus(), w.GetLogger()) + + oSrv := (w.services["order"]).(*service.OrderService) + + msgs, err := w.GetEventBus().Consume( + w.cnf.EventBusQueue, // queue + "", // consumer + false, // auto-ack + false, // exclusive + false, // no-local + false, // no-wait + nil, // args + ) + if err != nil { + w.GetLogger().Log("Failed to register a consumer: %s", err) + os.Exit(1) + //close(while) + } + + go func() { + for d := range msgs { + // go func(d amqp.Delivery) { + w.processMsg(oSrv, d) + // }(d) + } + }() + <-while + + return nil +} + +func (w *Worker) processMsg(srvc *service.OrderService, m amqp.Delivery) { + msg, err := rabbitmq.Deserialize(m.Body) + if err != nil { + w.GetLogger().Log("Deserialization error: %v\n", err) + m.Reject(false) + + return + } + + name := fmt.Sprintf("%s", msg["event"]) + data := (msg["data"]).(map[string]interface{}) + // reqID := (data["request_id"]).(string) // FIXME Check input params! + + w.GetLogger().Log("Processing message \"%s\" with data: %v\n", name, data) + + var ok = false + switch true { // Refactor -> use case for polymorphism + case strings.Contains(name, event.EVENT_BASKET_CHECKOUT): + w.GetLogger().Log("Event: %s", event.EVENT_BASKET_CHECKOUT) + } + + rnr := NewCommandRunner(data, srvc) + + // case strings.Contains(name, event.EVENT_PRODUCT_ADDED_TO_BASKET): + // basketID := data["basket_id"].(string) // FIXME Check input params! + // productID := data["product_id"] // FIXME Check input params! + + // rnr.cmd = &AddProductToBasketCommand{srvc} + // w.Logger.Log("Adding product #%d to basket #%s. ReqID: #%s", productID, basketID, reqID) + // case strings.Contains(name, event.EVENT_PRODUCT_REMOVED_FROM_BASKET): + // basketID := data["basket_id"].(string) + // productID := data["product_id"].(float64) + + // rnr.cmd = &RemoveProductFromBasketCommand{srvc} + // w.Logger.Log("Removing product #%d from basket #%s. ReqID: #%s", productID, basketID, reqID) + // } + + ok, _ = rnr.run(data) + if ok { + w.GetLogger().Log("Successful executed message \"%s\"\n", name) + m.Ack(false) + return + } + + w.GetLogger().Log("Error processing \"%s\": %s (%v)", name, err.Error(), err) + m.Reject(false) // FIXME: or Nack(repeat until success - maybe message shout know...? +} diff --git a/src/internal/app/database/connect.go b/src/pkg/database/connect.go similarity index 54% rename from src/internal/app/database/connect.go rename to src/pkg/database/connect.go index b44cfdd..e8c889c 100644 --- a/src/internal/app/database/connect.go +++ b/src/pkg/database/connect.go @@ -3,14 +3,14 @@ package database import ( "context" - "github.com/jackc/pgx/v4/pgxpool" + "github.com/jackc/pgx/v5/pgxpool" ) func Connect(connStr string) (*pgxpool.Pool, error) { - conn, err := pgxpool.Connect(context.Background(), connStr) + pool, err := pgxpool.New(context.Background(), connStr) if err != nil { return nil, err } - return conn, nil + return pool, nil } -- 2.39.5 From 6ed50098823eea10fd56d21000de523447fad878 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 19 Jul 2024 21:51:51 +0200 Subject: [PATCH 15/18] fix --- .env.dist | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.env.dist b/.env.dist index 1b1e7dd..ab4da55 100644 --- a/.env.dist +++ b/.env.dist @@ -1,15 +1,15 @@ -SERVER_ADDR=:1883 +SERVER_ADDR=:80 APP_NAME=order-svc -APP_DOMAIN=host.docker.internal -REGISTRY_USE_DOMAIN_OVER_IP=true +APP_DOMAIN=order.service.ego.io +REGISTRY_USE_DOMAIN_OVER_IP=false APP_PATH_PREFIX=/order APP_KV_NAMESPACE=dev.egommerce/service/order-svc -LOGGER_ADDR=egommerce.local:48400 -REGISTRY_ADDR=egommerce.local:48100 -DATABASE_URL=postgres://postgres:12345678@egommerce.local:48500/egommerce -CACHE_ADDR=egommerce.local:48300 +LOGGER_ADDR=api-logger:24224 +REGISTRY_ADDR=api-registry:8500 +DATABASE_URL=postgres://postgres:12345678@postgres-db:5432/egommerce +CACHE_ADDR=api-cache:6379 CACHE_PASSWORD=12345678 -MONGODB_URL=mongodb://mongodb:12345678@egommerce.local:48600 -EVENTBUS_URL=amqp://guest:guest@egommerce.local:48201 +MONGODB_URL=mongodb://mongodb:12345678@mongo-db:27017 +EVENTBUS_URL=amqp://guest:guest@api-eventbus:5672 -- 2.39.5 From a7447978bec174bf53005287aa9d40a7c7b8cbf1 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 19 Jul 2024 22:46:16 +0200 Subject: [PATCH 16/18] fixes --- .gitignore | 6 ++ src/internal/worker/ext.go | 133 ------------------------------------- 2 files changed, 6 insertions(+), 133 deletions(-) create mode 100644 .gitignore delete mode 100644 src/internal/worker/ext.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c1faf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.env +.env.* +!.env.dist + +.vscode/ +__debug_bin \ No newline at end of file diff --git a/src/internal/worker/ext.go b/src/internal/worker/ext.go deleted file mode 100644 index e71faff..0000000 --- a/src/internal/worker/ext.go +++ /dev/null @@ -1,133 +0,0 @@ -package worker - -// import ( -// "bytes" -// "encoding/json" -// "os" -// "time" - -// "git.pbiernat.io/egommerce/go-api-pkg/consul" -// "git.pbiernat.io/egommerce/go-api-pkg/fluentd" -// "git.pbiernat.io/egommerce/go-api-pkg/rabbitmq" -// cnf "git.pbiernat.io/egommerce/order-service/internal/config" -// "git.pbiernat.io/egommerce/order-service/pkg/database" -// "github.com/go-redis/redis/v8" -// ) - -// func WithCache(c *cnf.Config) OptionFn { -// return func(w *Worker) error { -// conn := redis.NewClient(&redis.Options{ -// Addr: c.CacheAddr, -// Password: c.CachePassword, -// DB: 0, -// }) - -// w.Cache = conn - -// return nil -// } -// } - -// func WithDatabase(c *cnf.Config) OptionFn { -// return func(w *Worker) error { -// conn, err := database.Connect(c.DbURL) -// if err != nil { -// w.Logger.Log("Failed to connect to Database server: %v\n", err) -// os.Exit(1) -// } - -// w.Database = conn - -// return nil -// } -// } - -// func WithEventbus(c *cnf.Config) OptionFn { -// return func(w *Worker) error { -// _, chn, err := rabbitmq.Open(c.EventBusURL) -// if err != nil { -// w.Logger.Log("Failed to connect to EventBus server: %v\n", err) -// os.Exit(1) -// } - -// err = rabbitmq.NewExchange(chn, c.EventBusExchange) -// if err != nil { -// w.Logger.Log("Failed to declare EventBus exchange: %v\n", err) -// os.Exit(1) -// } - -// _, err = chn.QueueDeclare( -// c.EventBusQueue, // name -// false, // durable -// false, // delete when unused -// false, // exclusive -// false, // no-wait -// nil, // arguments -// ) -// if err != nil { -// w.Logger.Log("Failed to declare EventBus queue: %v\n", err) -// os.Exit(1) -// } - -// // w.bindQueues() -// rabbitmq.BindQueueToExchange(chn, c.EventBusQueue, c.EventBusExchange, "basket.order.basketCheckout") - -// w.Eventbus = chn - -// return nil -// } -// } - -// func WithLogger(c *cnf.Config) OptionFn { -// return func(w *Worker) error { -// logHost, logPort, err := fluentd.ParseAddr(c.LoggerAddr) -// if err != nil { -// w.Logger.Log("Failed to parse Fluentd address: %s. Err: %v", c.LoggerAddr, err) -// os.Exit(1) -// } - -// logger, err := fluentd.NewLogger(c.Base.GetAppFullName(), logHost, logPort) -// if err != nil { -// w.Logger.Log("Failed to connect to the Fluentd on %s:%d. Err: %v", logHost, logPort, err) -// os.Exit(1) -// } - -// w.Logger = logger - -// return nil -// } -// } - -// func WithRegistry(c *cnf.Config) OptionFn { -// return func(w *Worker) error { -// registry, err := consul.NewService(c.RegistryAddr, c.Base.AppID, c.Base.AppName, c.Base.AppID, "", "", 0) -// if err != nil { -// w.Logger.Log("Error connecting to %s: %v", c.RegistryAddr, err) -// } - -// w.Registry = registry - -// go func(w *Worker) { // Fetch Consul KV config and store it in app config -// ticker := time.NewTicker(time.Second * 15) -// for range ticker.C { -// fetchKVConfig(w) // FIXME: duplicated in server -// } -// }(w) - -// return nil -// } - -// } - -// func fetchKVConfig(w *Worker) { // @FIXME: merge duplication in server.go and worker.go -// config, _, err := w.Registry.KV().Get(w.Config.KVNamespace, nil) -// if err != nil || config == nil { -// return -// } - -// kvCnf := bytes.NewBuffer(config.Value) -// decoder := json.NewDecoder(kvCnf) -// if err := decoder.Decode(&w.Config); err != nil { -// return -// } -// } -- 2.39.5 From 544298eb991fe1b281986842c7bb09eae4f1d5d9 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Sat, 20 Jul 2024 19:23:18 +0200 Subject: [PATCH 17/18] refactor, TLS support, v0.5 --- .app.config | 14 +++++++ .env.dist | 2 +- Dockerfile.target | 5 ++- bin/entrypoint.sh | 2 +- src/cmd/migrate/main.go | 2 +- src/go.mod | 2 +- src/go.sum | 4 +- src/internal/server/config.go | 2 +- src/internal/server/server.go | 12 +++++- src/internal/worker/worker.go | 70 +++++++++++++++++++++-------------- 10 files changed, 76 insertions(+), 39 deletions(-) create mode 100644 .app.config diff --git a/.app.config b/.app.config new file mode 100644 index 0000000..b0455ba --- /dev/null +++ b/.app.config @@ -0,0 +1,14 @@ +{ + "ID": "order", + "Name": "order", + "Address": "__IP__", + "Tags": ["order-svc", "order", "https", "service"], + "Port": 443, + "Connect": { + "Native": true + }, + "Check": { + "TCP": "__IP__:443", + "DeregisterCriticalServiceAfter": "10s" + } +} \ No newline at end of file diff --git a/.env.dist b/.env.dist index ab4da55..5e442c4 100644 --- a/.env.dist +++ b/.env.dist @@ -1,4 +1,4 @@ -SERVER_ADDR=:80 +SERVER_ADDR=:443 APP_NAME=order-svc APP_DOMAIN=order.service.ego.io diff --git a/Dockerfile.target b/Dockerfile.target index a934e6f..1f0475d 100644 --- a/Dockerfile.target +++ b/Dockerfile.target @@ -21,13 +21,14 @@ WORKDIR / COPY --from=builder $BIN_OUTPUT /app COPY --from=builder /go/bin/migrate /bin/migrate COPY --from=builder /go/bin/health /bin/health -COPY .env.dist /.env +COPY .env.docker /.env +COPY ./.app.config / COPY ./bin /bin RUN chmod 755 /bin/entrypoint.sh /bin/migrate.sh RUN apk add curl -EXPOSE 80 +EXPOSE 443 ENTRYPOINT ["entrypoint.sh"] CMD ["sh", "-c", "/app"] diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 44acbde..764b78e 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -21,7 +21,7 @@ waitForService "api-registry:8500" waitForService "postgres-db:5432" waitForService "api-eventbus:5672" waitForService "api-logger:24224" -waitForService "basket-svc:80" +waitForService "basket-svc:443" # run migrations migrate.sh diff --git a/src/cmd/migrate/main.go b/src/cmd/migrate/main.go index 7002eac..c504aed 100644 --- a/src/cmd/migrate/main.go +++ b/src/cmd/migrate/main.go @@ -55,7 +55,7 @@ func main() { log.Fatalf("Error parsing logger addr: %s. Err: %v", c.LoggerAddr, err) } - logger, err := fluentd.NewLogger(c.Base.GetAppFullName(), logHost, logPort) // @Refactor NewLogger return (logger, error) + logger, err := fluentd.NewLogger(c.GetAppFullName(), logHost, logPort) // @Refactor NewLogger return (logger, error) if err != nil { log.Fatalf("Error connecting to %s:%d. Err: %v", logHost, logPort, err) } diff --git a/src/go.mod b/src/go.mod index baa7128..7dbd68c 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( git.pbiernat.io/egommerce/api-entities v0.2.3 - git.pbiernat.io/egommerce/go-api-pkg v0.2.88 + git.pbiernat.io/egommerce/go-api-pkg v0.3.18 github.com/georgysavva/scany/v2 v2.0.0 github.com/go-pg/migrations/v8 v8.1.0 github.com/go-pg/pg/v10 v10.10.7 diff --git a/src/go.sum b/src/go.sum index 2b583aa..71deaec 100644 --- a/src/go.sum +++ b/src/go.sum @@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= git.pbiernat.io/egommerce/api-entities v0.2.3 h1:mR6EYfZkAzh4teydb7KXDBWoxwVW3qasnmmH5J3mnas= git.pbiernat.io/egommerce/api-entities v0.2.3/go.mod h1:INXAG5x4+i+vNwg1NpfPHiDW8nY1kn1K7pgLOtX+/I0= -git.pbiernat.io/egommerce/go-api-pkg v0.2.88 h1:xya/39BnFeha3Oc76ad/ppoQd6AstTGQd87Qszamr1A= -git.pbiernat.io/egommerce/go-api-pkg v0.2.88/go.mod h1:XIy2mmvRNIzQmYIUAcDZafhRPxTQFS2HDmsK7ZQ6980= +git.pbiernat.io/egommerce/go-api-pkg v0.3.18 h1:0+C9BMsllrNvRbh4kb7dJ5lrzP1Lc7J4pb+KV76YrXk= +git.pbiernat.io/egommerce/go-api-pkg v0.3.18/go.mod h1:XIy2mmvRNIzQmYIUAcDZafhRPxTQFS2HDmsK7ZQ6980= github.com/Azure/azure-sdk-for-go v44.0.0+incompatible h1:e82Yv2HNpS0kuyeCrV29OPKvEiqfs2/uJHic3/3iKdg= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM= diff --git a/src/internal/server/config.go b/src/internal/server/config.go index b94d787..8419411 100644 --- a/src/internal/server/config.go +++ b/src/internal/server/config.go @@ -18,7 +18,7 @@ const ( defEventBusURL = "amqp://guest:guest@api-eventbus:5672" defKVNmspc = "dev.egommerce/service/order" defLoggerAddr = "api-logger:24224" - defNetAddr = ":80" + defNetAddr = ":443" defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" defPathPrefix = "/order" defRegistryAddr = "api-registry:8500" diff --git a/src/internal/server/server.go b/src/internal/server/server.go index 6799c72..1bfa7b6 100644 --- a/src/internal/server/server.go +++ b/src/internal/server/server.go @@ -1,6 +1,8 @@ package server import ( + "crypto/tls" + "log" "net" "time" @@ -19,7 +21,7 @@ type ( *fiber.App ID string - addr string // e.g. "127.0.0.1:80" + addr string // e.g. "127.0.0.1:443" handlers map[string]any } HeaderRequestID struct { @@ -47,8 +49,14 @@ func (s *Server) Start() error { SetupRouter(s) // fmt.Printf("Starting server at: %s...\n", s.addr) + cer, err := tls.LoadX509KeyPair("certs/client.crt", "certs/client.key") + if err != nil { + log.Fatal(err) + } + tlsCnf := &tls.Config{Certificates: []tls.Certificate{cer}} + ln, _ := net.Listen("tcp", s.addr) - // ln = tls.NewListener(ln, s.App.Server().TLSConfig) + ln = tls.NewListener(ln, tlsCnf) return s.Listener(ln) } diff --git a/src/internal/worker/worker.go b/src/internal/worker/worker.go index e70b51f..8359e8e 100644 --- a/src/internal/worker/worker.go +++ b/src/internal/worker/worker.go @@ -38,34 +38,9 @@ func New(c *Config) *Worker { } func (w *Worker) Start() error { - // Init - err := rabbitmq.NewExchange(w.GetEventBus(), w.cnf.EventBusExchange) - if err != nil { - w.GetLogger().Log("Failed to declare EventBus exchange: %v\n", err) - fmt.Printf("Failed to declare EventBus exchange: %v\n", err) + setupQueues(w) - os.Exit(1) - } - - _, err = w.GetEventBus().QueueDeclare( - w.cnf.EventBusQueue, // name - false, // durable - false, // delete when unused - false, // exclusive - false, // no-wait - nil, // arguments - ) - if err != nil { - w.GetLogger().Log("Failed to declare EventBus queue: %v\n", err) - fmt.Printf("Failed to declare EventBus queue: %v\n", err) - - os.Exit(1) - } - - // // w.bindQueues() - rabbitmq.BindQueueToExchange(w.GetEventBus(), w.cnf.EventBusQueue, w.cnf.EventBusExchange, "basket.order.basketCheckout") - - err = w.doWork(w.doWrkUntil) + err := w.doWork(w.doWrkUntil) if err != nil { log.Fatalf("Failed to start worker: %s. Reason: %v\n", w.ID, err) close(w.doWrkUntil) @@ -99,6 +74,8 @@ func (w *Worker) RegisterHandler(name string, fn func() any) { func (w *Worker) OnShutdown() { w.GetLogger().Log("Worker %s is going down...", w.ID) // fmt.Printf("Worker %s is going down...\n", w.ID) + + unbindQueues(w) w.GetEventBus().Close() w.GetDatabase().Close() w.GetLogger().Log("Gone.") @@ -161,6 +138,7 @@ func (w *Worker) processMsg(srvc *service.OrderService, m amqp.Delivery) { msg, err := rabbitmq.Deserialize(m.Body) if err != nil { w.GetLogger().Log("Deserialization error: %v\n", err) + fmt.Printf("Deserialization error: %v\n", err) m.Reject(false) return @@ -171,6 +149,7 @@ func (w *Worker) processMsg(srvc *service.OrderService, m amqp.Delivery) { // reqID := (data["request_id"]).(string) // FIXME Check input params! w.GetLogger().Log("Processing message \"%s\" with data: %v\n", name, data) + fmt.Printf("Processing message \"%s\" with data: %v\n", name, data) var ok = false switch true { // Refactor -> use case for polymorphism @@ -197,10 +176,45 @@ func (w *Worker) processMsg(srvc *service.OrderService, m amqp.Delivery) { ok, _ = rnr.run(data) if ok { w.GetLogger().Log("Successful executed message \"%s\"\n", name) + fmt.Printf("Successful executed message \"%s\"\n", name) m.Ack(false) return } - w.GetLogger().Log("Error processing \"%s\": %s (%v)", name, err.Error(), err) + w.GetLogger().Log("Error processing \"%s\": %v", name, err) + fmt.Printf("Error processing \"%s\": %v\n", name, err) m.Reject(false) // FIXME: or Nack(repeat until success - maybe message shout know...? } + +func setupQueues(w *Worker) { + err := rabbitmq.NewExchange(w.GetEventBus(), w.cnf.EventBusExchange) + if err != nil { + w.GetLogger().Log("Failed to declare EventBus exchange: %v\n", err) + fmt.Printf("Failed to declare EventBus exchange: %v\n", err) + + os.Exit(1) + } + + args := amqp.Table{} + args["x-message-ttl"] = 5 + _, err = w.GetEventBus().QueueDeclare( + w.cnf.EventBusQueue, // name + true, // durable + false, // delete when unused + false, // exclusive + false, // no-wait + args, // arguments + ) + if err != nil { + w.GetLogger().Log("Failed to declare EventBus queue: %v\n", err) + fmt.Printf("Failed to declare EventBus queue: %v\n", err) + + os.Exit(1) + } + + rabbitmq.BindQueueToExchange(w.GetEventBus(), w.cnf.EventBusQueue, w.cnf.EventBusExchange, "basket.order.basketCheckout") +} + +func unbindQueues(w *Worker) { + w.GetEventBus().QueueUnbind(w.cnf.EventBusQueue, "basket.order.basketCheckout", w.cnf.EventBusExchange, nil) +} -- 2.39.5 From 2584e23826cd43409031c302ceef30f40858820e Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Thu, 5 Dec 2024 17:00:16 +0100 Subject: [PATCH 18/18] Update --- .app.config | 2 ++ .env.dist | 2 +- bin/entrypoint.sh | 6 ++++-- src/cmd/health/main.go | 2 +- src/cmd/server/main.go | 2 +- src/go.mod | 2 +- src/go.sum | 4 ++-- src/internal/server/config.go | 2 +- src/internal/server/middleware.go | 10 ++++------ src/internal/server/server.go | 2 +- 10 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.app.config b/.app.config index b0455ba..15d793b 100644 --- a/.app.config +++ b/.app.config @@ -9,6 +9,8 @@ }, "Check": { "TCP": "__IP__:443", + "Interval": "5s", + "Timeout": "1s", "DeregisterCriticalServiceAfter": "10s" } } \ No newline at end of file diff --git a/.env.dist b/.env.dist index 5e442c4..1ebc14a 100644 --- a/.env.dist +++ b/.env.dist @@ -7,7 +7,7 @@ APP_PATH_PREFIX=/order APP_KV_NAMESPACE=dev.egommerce/service/order-svc LOGGER_ADDR=api-logger:24224 -REGISTRY_ADDR=api-registry:8500 +REGISTRY_ADDR=api-registry:8501 DATABASE_URL=postgres://postgres:12345678@postgres-db:5432/egommerce CACHE_ADDR=api-cache:6379 CACHE_PASSWORD=12345678 diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 764b78e..6a9ebc8 100755 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -17,12 +17,14 @@ waitForService() update-resolv # provided by stack - better approach - single copy update-ca-certificates -waitForService "api-registry:8500" -waitForService "postgres-db:5432" +waitForService "api-registry:8501" waitForService "api-eventbus:5672" waitForService "api-logger:24224" +waitForService "db-postgres:5432" waitForService "basket-svc:443" +register-service + # run migrations migrate.sh diff --git a/src/cmd/health/main.go b/src/cmd/health/main.go index c27f125..4c4420e 100644 --- a/src/cmd/health/main.go +++ b/src/cmd/health/main.go @@ -29,7 +29,7 @@ func main() { } func healthCheck() bool { - run, err := os.Open("/app.run") + run, err := os.Open("./app.run") if err != nil { return false } diff --git a/src/cmd/server/main.go b/src/cmd/server/main.go index 8c56272..0f0c879 100644 --- a/src/cmd/server/main.go +++ b/src/cmd/server/main.go @@ -25,7 +25,7 @@ func main() { a.RegisterPlugin(app.CachePlugin(cArr)) a.RegisterPlugin(app.DatabasePlugin(cArr)) a.RegisterPlugin(app.EventbusPlugin(cArr)) - a.RegisterPlugin(app.RegistryPlugin(cArr)) + // a.RegisterPlugin(app.RegistryPlugin(cArr)) while := make(chan struct{}) err := a.Start(while) diff --git a/src/go.mod b/src/go.mod index 7dbd68c..0c1b678 100644 --- a/src/go.mod +++ b/src/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( git.pbiernat.io/egommerce/api-entities v0.2.3 - git.pbiernat.io/egommerce/go-api-pkg v0.3.18 + git.pbiernat.io/egommerce/go-api-pkg v0.3.24 github.com/georgysavva/scany/v2 v2.0.0 github.com/go-pg/migrations/v8 v8.1.0 github.com/go-pg/pg/v10 v10.10.7 diff --git a/src/go.sum b/src/go.sum index 71deaec..e0ae567 100644 --- a/src/go.sum +++ b/src/go.sum @@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= git.pbiernat.io/egommerce/api-entities v0.2.3 h1:mR6EYfZkAzh4teydb7KXDBWoxwVW3qasnmmH5J3mnas= git.pbiernat.io/egommerce/api-entities v0.2.3/go.mod h1:INXAG5x4+i+vNwg1NpfPHiDW8nY1kn1K7pgLOtX+/I0= -git.pbiernat.io/egommerce/go-api-pkg v0.3.18 h1:0+C9BMsllrNvRbh4kb7dJ5lrzP1Lc7J4pb+KV76YrXk= -git.pbiernat.io/egommerce/go-api-pkg v0.3.18/go.mod h1:XIy2mmvRNIzQmYIUAcDZafhRPxTQFS2HDmsK7ZQ6980= +git.pbiernat.io/egommerce/go-api-pkg v0.3.24 h1:if6xsFOStckWdGm7kcgKWOhOGOe6iIBOOr+3DjgX5tM= +git.pbiernat.io/egommerce/go-api-pkg v0.3.24/go.mod h1:XIy2mmvRNIzQmYIUAcDZafhRPxTQFS2HDmsK7ZQ6980= github.com/Azure/azure-sdk-for-go v44.0.0+incompatible h1:e82Yv2HNpS0kuyeCrV29OPKvEiqfs2/uJHic3/3iKdg= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM= diff --git a/src/internal/server/config.go b/src/internal/server/config.go index 8419411..1e97fd7 100644 --- a/src/internal/server/config.go +++ b/src/internal/server/config.go @@ -21,7 +21,7 @@ const ( defNetAddr = ":443" defMongoDbURL = "mongodb://mongodb:12345678@mongo-db:27017" defPathPrefix = "/order" - defRegistryAddr = "api-registry:8500" + defRegistryAddr = "api-registry:8501" defEbEventsExchange = "api-events" defEbEventsQueue = "order-svc" ) diff --git a/src/internal/server/middleware.go b/src/internal/server/middleware.go index 32328d9..8c7a36c 100644 --- a/src/internal/server/middleware.go +++ b/src/internal/server/middleware.go @@ -1,8 +1,6 @@ package server import ( - "strings" - "github.com/gofiber/fiber/v2" "git.pbiernat.io/egommerce/go-api-pkg/fluentd" @@ -17,10 +15,10 @@ func SetupMiddleware(s *Server) { func LoggingMiddleware(log *fluentd.Logger) func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { - path := string(c.Request().URI().Path()) - if strings.Contains(path, "/health") { - return c.Next() - } + // path := string(c.Request().URI().Path()) + // if strings.Contains(path, "/health") { + // return c.Next() + // } log.Log("Request: %s, remote: %s, via: %s", c.Request().URI().String(), diff --git a/src/internal/server/server.go b/src/internal/server/server.go index 1bfa7b6..e76063e 100644 --- a/src/internal/server/server.go +++ b/src/internal/server/server.go @@ -69,7 +69,7 @@ func (s *Server) RegisterHandler(name string, fn func() any) { func (s *Server) OnShutdown() { // s.GetLogger().Log("Server %s is going down...", s.ID) - s.GetRegistry().Unregister() + // s.GetRegistry().Unregister() // a.clearMetadataCache() s.GetEventBus().Close() s.GetDatabase().Close() -- 2.39.5