diff --git a/hw12_13_14_15_calendar/Makefile b/hw12_13_14_15_calendar/Makefile index 870efcf..a0af979 100644 --- a/hw12_13_14_15_calendar/Makefile +++ b/hw12_13_14_15_calendar/Makefile @@ -5,7 +5,7 @@ build: go build -o ./bin ./... test: - go test -race ./... + go test -race -v `go list ./... | grep -v integration-tests` lint: golangci-lint run ./... @@ -18,8 +18,16 @@ launch: run: make build && make launch -migrate: - ./scripts/migrations.sh +up: + docker-compose -f deployments/docker-compose.yml up -d + +down: + docker-compose -f deployments/docker-compose.yml down + +integration-tests: + docker-compose -f deployments/docker-compose.yml -f deployments/docker-compose.test.yml up -d --build && \ + API_HOST=http://localhost:8888 ginkgo ./integration-tests && \ + docker-compose -f deployments/docker-compose.yml -f deployments/docker-compose.test.yml down generate: protoc \ @@ -29,4 +37,4 @@ generate: --grpc-gateway_out=logtostderr=true:${cdir}/service/server \ ${cdir}/service/schema/calendar.proto -.PHONY: build +.PHONY: build integration-tests diff --git a/hw12_13_14_15_calendar/cmd/calendar_scheduler/main.go b/hw12_13_14_15_calendar/cmd/calendar_scheduler/main.go index ac5c3b6..da18ba4 100644 --- a/hw12_13_14_15_calendar/cmd/calendar_scheduler/main.go +++ b/hw12_13_14_15_calendar/cmd/calendar_scheduler/main.go @@ -3,8 +3,6 @@ package main import ( "context" "flag" - "fmt" - "strconv" "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/config" "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/logger" @@ -49,7 +47,7 @@ func main() { qCfg := cfg.QueueConfig producer := queue.NewProducer( - fmt.Sprintf("amqp://%s:%s@%s:%s/", qCfg.User, qCfg.Pass, qCfg.Host, strconv.Itoa(qCfg.Port)), + qCfg.URI, qCfg.QueueName, qCfg.ExchangeType, qCfg.MaxReconnectAttempts, diff --git a/hw12_13_14_15_calendar/cmd/calendar_sender/main.go b/hw12_13_14_15_calendar/cmd/calendar_sender/main.go index ea2097b..fcb3243 100644 --- a/hw12_13_14_15_calendar/cmd/calendar_sender/main.go +++ b/hw12_13_14_15_calendar/cmd/calendar_sender/main.go @@ -1,13 +1,13 @@ package main import ( + "context" "flag" - "fmt" - "strconv" "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/config" "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/logger" "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/queue" + "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/repository" "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/sender" "github.com/rs/zerolog/log" ) @@ -24,6 +24,8 @@ func init() { func main() { flag.Parse() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() cfg, err := config.NewSender(cfgPath) if err != nil { @@ -34,17 +36,26 @@ func main() { fatal(err) } - qCfg := cfg.QueueConfig + repo := repository.NewStats(cfg.DBConfig.RepoType, cfg.DBConfig.ItemsPerQuery, cfg.DBConfig.MaxConn) + if repo == nil { + fatal(repository.ErrUnSupportedRepoType) + } + + if err = repo.Connect(ctx, repository.GetSQLDSN(&cfg.DBConfig)); err != nil { + fatal(err) + } + defer repo.Close() + qCfg := cfg.QueueConfig consumer := queue.NewConsumer( - fmt.Sprintf("amqp://%s:%s@%s:%s/", qCfg.User, qCfg.Pass, qCfg.Host, strconv.Itoa(qCfg.Port)), + qCfg.URI, qCfg.QueueName, qCfg.ExchangeType, qCfg.QosPrefetchCount, qCfg.MaxReconnectAttempts, qCfg.ReconnectTimeoutMs, ) - app := sender.New(consumer, qCfg.ScanTimeoutMs) + app := sender.New(repo, consumer, qCfg.ScanTimeoutMs) if err := app.Run(); err != nil { fatal(err) } diff --git a/hw12_13_14_15_calendar/configs/calendar.yml b/hw12_13_14_15_calendar/configs/calendar.yml index a0ccfa7..7fe2b95 100644 --- a/hw12_13_14_15_calendar/configs/calendar.yml +++ b/hw12_13_14_15_calendar/configs/calendar.yml @@ -10,7 +10,7 @@ dbConfig: port: 5432 dbName: "db_calendar" user: "db_calendar_user" - pass: "test" + password: "test" itemsPerQuery: 50 repoType: "psql" diff --git a/hw12_13_14_15_calendar/configs/sender.yml b/hw12_13_14_15_calendar/configs/sender.yml index 258fc06..9fd9d3a 100644 --- a/hw12_13_14_15_calendar/configs/sender.yml +++ b/hw12_13_14_15_calendar/configs/sender.yml @@ -3,9 +3,6 @@ logConfig: filePath: "calendar_sender.log" queueConfig: - user: "guest" - pass: "guest" - host: "localhost" - port: 5672 + uri: "amqp://guest:guest@localhost:5672/" queueName: "events" scanTimeout: 10 \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/Dockerfile b/hw12_13_14_15_calendar/deployments/Dockerfile new file mode 100644 index 0000000..0569f7f --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/Dockerfile @@ -0,0 +1,31 @@ +FROM golang:1.14-alpine AS builder + +RUN apk update + +# Set necessary environmet variables needed for our image +ENV GO111MODULE=on \ + CGO_ENABLED=0 \ + GOOS=linux + +WORKDIR /build + +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the code into the container +COPY . . + +ARG MAIN_FILE_PATH + +# Build the application +RUN go build -o main $MAIN_FILE_PATH +RUN chmod +x main + +# Build a small image +FROM scratch + +COPY --from=builder /build/main / +EXPOSE 8081 + +# Command to run +ENTRYPOINT ["/main"] \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/api.env b/hw12_13_14_15_calendar/deployments/api.env new file mode 100644 index 0000000..9732a4c --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/api.env @@ -0,0 +1,2 @@ +GRPC_ADDRESS=0.0.0.0:50051 +HTTP_ADDRESS=0.0.0.0:50052 \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/database.env b/hw12_13_14_15_calendar/deployments/database.env new file mode 100644 index 0000000..386141f --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/database.env @@ -0,0 +1,7 @@ +DB_HOST=db +DB_PORT=5432 +DB_USER=db_calendar_user +DB_PASSWORD=test +DB_NAME=db_calendar +DB_REPO_TYPE=psql +DB_ITEMS_PER_QUERY=50 \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/database_test.env b/hw12_13_14_15_calendar/deployments/database_test.env new file mode 100644 index 0000000..c460e1c --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/database_test.env @@ -0,0 +1 @@ +DB_NAME=db_calendar_test \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/docker-compose.prod.yml b/hw12_13_14_15_calendar/deployments/docker-compose.prod.yml new file mode 100644 index 0000000..eb89915 --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/docker-compose.prod.yml @@ -0,0 +1,10 @@ +version: "2.4" + +services: + db: + volumes: + - pg_volume:/var/lib/postgresql/data + +volumes: + pg_volume: + driver: local \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/docker-compose.test.yml b/hw12_13_14_15_calendar/deployments/docker-compose.test.yml new file mode 100644 index 0000000..a9f8bc7 --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/docker-compose.test.yml @@ -0,0 +1,20 @@ +version: "2.4" + +services: + db: + environment: + - POSTGRES_DB=db_calendar_test + migrator: + env_file: + - database_test.env + calendar: + env_file: + - database_test.env + calendar_scheduler: + env_file: + - database_test.env + - queue_test.env + calendar_sender: + env_file: + - database_test.env + - queue_test.env \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/docker-compose.yml b/hw12_13_14_15_calendar/deployments/docker-compose.yml new file mode 100644 index 0000000..04ed9c1 --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/docker-compose.yml @@ -0,0 +1,94 @@ +version: "2.4" + +services: + db: + image: postgres:12 + environment: + - POSTGRES_USER=db_calendar_user + - POSTGRES_PASSWORD=test + - POSTGRES_DB=db_calendar + ports: + - "5432:5432" + healthcheck: + test: ["CMD", "pg_isready", "-U", "$POSTGRES_USER"] + interval: 10s + timeout: 10s + retries: 3 + start_period: 20s + migrator: + build: + context: ../ + dockerfile: ./deployments/migrator/Dockerfile + env_file: + - database.env + depends_on: + db: + condition: service_healthy + queue: + build: + context: ./rabbitmq + environment: + - RABBITMQ_DEFAULT_USER=guest + - RABBITMQ_DEFAULT_PASS=guest + healthcheck: + test: [ "CMD", "nc", "-z", "localhost", "5672" ] + interval: 10s + timeout: 10s + retries: 3 + start_period: 20s + ports: + - "5672:5672" + - "15672:15672" + calendar: + build: + context: ../ + dockerfile: ./deployments/Dockerfile + args: + - MAIN_FILE_PATH=cmd/calendar/main.go + env_file: + - database.env + - logger.env + - api.env + environment: + - PORT=8081 + volumes: + - ../migrations:/migrations + ports: + - "8888:50052" + depends_on: + db: + condition: service_healthy + calendar_scheduler: + build: + context: ../ + dockerfile: ./deployments/Dockerfile + args: + - MAIN_FILE_PATH=cmd/calendar_scheduler/main.go + env_file: + - database.env + - logger.env + - queue.env + volumes: + - ../migrations:/migrations + depends_on: + db: + condition: service_healthy + queue: + condition: service_healthy + calendar_sender: + build: + context: ../ + dockerfile: ./deployments/Dockerfile + args: + - MAIN_FILE_PATH=cmd/calendar_sender/main.go + env_file: + - database.env + - logger.env + - queue.env + volumes: + - ../migrations:/migrations + depends_on: + db: + condition: service_healthy + queue: + condition: service_healthy \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/logger.env b/hw12_13_14_15_calendar/deployments/logger.env new file mode 100644 index 0000000..094c16f --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/logger.env @@ -0,0 +1,2 @@ +LOG_LEVEL=debug +LOG_FILE=calendar.log \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/migrator/Dockerfile b/hw12_13_14_15_calendar/deployments/migrator/Dockerfile new file mode 100644 index 0000000..6da5fb4 --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/migrator/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.14-alpine + +RUN apk update + +ENV GO111MODULE=on \ + CGO_ENABLED=0 \ + GOOS=linux + +WORKDIR /build + +# install goose +RUN go get 'github.com/pressly/goose/cmd/goose' + +# mount the app +RUN mkdir -p /opt/db +COPY ./migrations /opt/db/migrations + +# define goose as the entrypoint +ENTRYPOINT /go/bin/goose -v -dir /opt/db/migrations postgres "host=$DB_HOST port=$DB_PORT user=$DB_USER password=$DB_PASSWORD dbname=$DB_NAME sslmode=disable" up \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/queue.env b/hw12_13_14_15_calendar/deployments/queue.env new file mode 100644 index 0000000..54b88de --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/queue.env @@ -0,0 +1,3 @@ +QUEUE_URI=amqp://guest:guest@queue:5672/ +QUEUE_NAME=events +QUEUE_SCAN_TIMEOUT_MS=10000 \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/queue_test.env b/hw12_13_14_15_calendar/deployments/queue_test.env new file mode 100644 index 0000000..fa30df9 --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/queue_test.env @@ -0,0 +1 @@ +QUEUE_NAME=events-tests \ No newline at end of file diff --git a/hw12_13_14_15_calendar/deployments/rabbitmq/Dockerfile b/hw12_13_14_15_calendar/deployments/rabbitmq/Dockerfile new file mode 100644 index 0000000..37e4acb --- /dev/null +++ b/hw12_13_14_15_calendar/deployments/rabbitmq/Dockerfile @@ -0,0 +1,3 @@ +FROM rabbitmq:3-management +RUN apt-get update +RUN apt-get install -y netcat \ No newline at end of file diff --git a/hw12_13_14_15_calendar/go.mod b/hw12_13_14_15_calendar/go.mod index c9e36f1..3d19f0a 100644 --- a/hw12_13_14_15_calendar/go.mod +++ b/hw12_13_14_15_calendar/go.mod @@ -7,17 +7,24 @@ require ( github.com/golang/protobuf v1.4.2 github.com/grpc-ecosystem/go-grpc-middleware v1.2.1 github.com/grpc-ecosystem/grpc-gateway v1.14.7 - github.com/heetch/confita v0.9.2 + github.com/ilyakaznacheev/cleanenv v1.2.5 github.com/imdario/mergo v0.3.11 github.com/jmoiron/sqlx v1.2.0 + github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.8.0 + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/onsi/ginkgo v1.14.1 + github.com/onsi/gomega v1.10.1 github.com/pkg/errors v0.9.1 // indirect github.com/pressly/goose v2.6.0+incompatible github.com/rs/zerolog v1.15.0 github.com/streadway/amqp v1.0.0 github.com/stretchr/testify v1.6.1 + golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect golang.org/x/text v0.3.3 // indirect + google.golang.org/appengine v1.6.1 // indirect google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70 google.golang.org/grpc v1.31.0 google.golang.org/protobuf v1.25.0 + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect ) diff --git a/hw12_13_14_15_calendar/go.sum b/hw12_13_14_15_calendar/go.sum index aa9f210..2db9fab 100644 --- a/hw12_13_14_15_calendar/go.sum +++ b/hw12_13_14_15_calendar/go.sum @@ -4,45 +4,26 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -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-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.3+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= 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/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/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +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/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= -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-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -55,13 +36,9 @@ github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GO github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= @@ -76,165 +53,86 @@ 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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -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/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 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.2.1 h1:V59tBiPuMkySHwJkuq/OYkK0WnOLwCwD3UkTbEMr12U= github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.6 h1:XvND7+MPP7Jp+JpqSZ7naSl5nVZf6k0LbL1V3EKh0zc= -github.com/grpc-ecosystem/grpc-gateway v1.8.6/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.7 h1:Nk5kuHrnWUTf/0GL1a/vchH/om9Ap2/HnVna+jYZgTY= github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -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/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= -github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.1/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/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-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= -github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/heetch/confita v0.9.2 h1:NNN99OG3xRgvBgpaVSFQht6/JrI7ax2kNKp2ayCSNR0= -github.com/heetch/confita v0.9.2/go.mod h1:W6GDCVPvi2LpvdEriwZTu2fyxuK+Grx1vY302gtWfvM= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ilyakaznacheev/cleanenv v1.2.5 h1:/SlcF9GaIvefWqFJzsccGG/NJdoaAwb7Mm7ImzhO3DM= +github.com/ilyakaznacheev/cleanenv v1.2.5/go.mod h1:/i3yhzwZ3s7hacNERGFwvlhwXMDcaqwIzmayEhbRplk= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 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/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +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.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= +github.com/onsi/ginkgo v1.14.1/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 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 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/pressly/goose v2.6.0+incompatible h1:3f8zIQ8rfgP9tyI0Hmcs2YNAqUCL1c+diLe3iU8Qd/k= github.com/pressly/goose v2.6.0+incompatible/go.mod h1:m+QHWCqxR3k8D9l7qfzuC/djtlfzxr34mozWDYEu1z8= -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 v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/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/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -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.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= 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/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 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 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/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-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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= @@ -249,52 +147,47 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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-20181023162649-9b4f9f5ad519/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-20181220203305-927f97764cc3/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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/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-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd h1:QPwSajcTUrFriMF1nJ3XzgoqakqQEsnZf9LdXdi2nkI= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 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/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-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/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-20190129075346-302c3dd5f1cc/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-20190215142949-d0b11bdaac8a/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-20190508220229-2d0786266e9c h1:hDn6jm7snBX2O7+EeTk6Q4WXJfKt7MWgtiCCRi1rBoY= -golang.org/x/sys v0.0.0-20190508220229-2d0786266e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/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-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= @@ -302,6 +195,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 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-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -309,9 +203,9 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -319,10 +213,7 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaR google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70 h1:wboULUXGF3c5qdUnKp+6gLAccE6PRpa/czkYvQ4UXv8= google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 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.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= @@ -341,21 +232,21 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= 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/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +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.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= +olympos.io/encoding/edn v0.0.0-20200308123125-93e3b8dd0e24 h1:sreVOrDp0/ezb0CHKVek/l7YwpxPJqv+jT3izfSphA4= +olympos.io/encoding/edn v0.0.0-20200308123125-93e3b8dd0e24/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw= diff --git a/hw12_13_14_15_calendar/integration-tests.output b/hw12_13_14_15_calendar/integration-tests.output new file mode 100644 index 0000000..68fcf66 --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests.output @@ -0,0 +1,221 @@ +make integration-tests +docker-compose -f deployments/docker-compose.yml -f deployments/docker-compose.test.yml up -d --build && \ + API_HOST=http://localhost:8888 ginkgo ./integration-tests && \ + docker-compose -f deployments/docker-compose.yml -f deployments/docker-compose.test.yml down +WARNING: The POSTGRES_USER variable is not set. Defaulting to a blank string. +Creating network "deployments_default" with the default driver +Building queue +Step 1/3 : FROM rabbitmq:3-management + ---> 9dd69c24b09f +Step 2/3 : RUN apt-get update + ---> Using cache + ---> 43f3b584ba90 +Step 3/3 : RUN apt-get install -y netcat + ---> Using cache + ---> 4dedbc3ea806 + +Successfully built 4dedbc3ea806 +Successfully tagged deployments_queue:latest +Building calendar_sender +Step 1/14 : FROM golang:1.14-alpine AS builder + ---> 0223ac8ea40d +Step 2/14 : RUN apk update + ---> Using cache + ---> 939d8313abf6 +Step 3/14 : ENV GO111MODULE=on CGO_ENABLED=0 GOOS=linux + ---> Using cache + ---> 64eb44d83ba8 +Step 4/14 : WORKDIR /build + ---> Using cache + ---> 87b7c58f74fe +Step 5/14 : COPY go.mod go.sum ./ + ---> Using cache + ---> 1695e50752d5 +Step 6/14 : RUN go mod download + ---> Using cache + ---> f2f881fd4fdb +Step 7/14 : COPY . . + ---> Using cache + ---> c018e3e1decb +Step 8/14 : ARG MAIN_FILE_PATH + ---> Using cache + ---> c5a8b9b7216f +Step 9/14 : RUN go build -o main $MAIN_FILE_PATH + ---> Using cache + ---> 7dc857d21e0c +Step 10/14 : RUN chmod +x main + ---> Using cache + ---> c7d5e14bf29d + +Step 11/14 : FROM scratch + ---> +Step 12/14 : COPY --from=builder /build/main / + ---> Using cache + ---> 7006fab2c329 +Step 13/14 : EXPOSE 8081 + ---> Using cache + ---> b64dfa29f5bf +Step 14/14 : ENTRYPOINT ["/main"] + ---> Using cache + ---> 574afba64b53 + +Successfully built 574afba64b53 +Successfully tagged deployments_calendar_sender:latest +Building migrator +Step 1/8 : FROM golang:1.14-alpine + ---> 0223ac8ea40d +Step 2/8 : RUN apk update + ---> Using cache + ---> 939d8313abf6 +Step 3/8 : ENV GO111MODULE=on CGO_ENABLED=0 GOOS=linux + ---> Using cache + ---> 64eb44d83ba8 +Step 4/8 : WORKDIR /build + ---> Using cache + ---> 87b7c58f74fe +Step 5/8 : RUN go get 'github.com/pressly/goose/cmd/goose' + ---> Using cache + ---> 37c8932f986d +Step 6/8 : RUN mkdir -p /opt/db + ---> Using cache + ---> 709d7c2c4467 +Step 7/8 : COPY ./migrations /opt/db/migrations + ---> Using cache + ---> fce54de0a0d6 +Step 8/8 : ENTRYPOINT /go/bin/goose -v -dir /opt/db/migrations postgres "host=$DB_HOST port=$DB_PORT user=$DB_USER password=$DB_PASSWORD dbname=$DB_NAME sslmode=disable" up + ---> Using cache + ---> 2a8b144dc191 + +Successfully built 2a8b144dc191 +Successfully tagged deployments_migrator:latest +Building calendar +Step 1/14 : FROM golang:1.14-alpine AS builder + ---> 0223ac8ea40d +Step 2/14 : RUN apk update + ---> Using cache + ---> 939d8313abf6 +Step 3/14 : ENV GO111MODULE=on CGO_ENABLED=0 GOOS=linux + ---> Using cache + ---> 64eb44d83ba8 +Step 4/14 : WORKDIR /build + ---> Using cache + ---> 87b7c58f74fe +Step 5/14 : COPY go.mod go.sum ./ + ---> Using cache + ---> 1695e50752d5 +Step 6/14 : RUN go mod download + ---> Using cache + ---> f2f881fd4fdb +Step 7/14 : COPY . . + ---> Using cache + ---> c018e3e1decb +Step 8/14 : ARG MAIN_FILE_PATH + ---> Using cache + ---> c5a8b9b7216f +Step 9/14 : RUN go build -o main $MAIN_FILE_PATH + ---> Using cache + ---> 6fe1758526a0 +Step 10/14 : RUN chmod +x main + ---> Using cache + ---> 34beafe8ea5b + +Step 11/14 : FROM scratch + ---> +Step 12/14 : COPY --from=builder /build/main / + ---> Using cache + ---> 2fac9a18f714 +Step 13/14 : EXPOSE 8081 + ---> Using cache + ---> 9a23c2b2318e +Step 14/14 : ENTRYPOINT ["/main"] + ---> Using cache + ---> a988a0f8f1f9 + +Successfully built a988a0f8f1f9 +Successfully tagged deployments_calendar:latest +Building calendar_scheduler +Step 1/14 : FROM golang:1.14-alpine AS builder + ---> 0223ac8ea40d +Step 2/14 : RUN apk update + ---> Using cache + ---> 939d8313abf6 +Step 3/14 : ENV GO111MODULE=on CGO_ENABLED=0 GOOS=linux + ---> Using cache + ---> 64eb44d83ba8 +Step 4/14 : WORKDIR /build + ---> Using cache + ---> 87b7c58f74fe +Step 5/14 : COPY go.mod go.sum ./ + ---> Using cache + ---> 1695e50752d5 +Step 6/14 : RUN go mod download + ---> Using cache + ---> f2f881fd4fdb +Step 7/14 : COPY . . + ---> Using cache + ---> c018e3e1decb +Step 8/14 : ARG MAIN_FILE_PATH + ---> Using cache + ---> c5a8b9b7216f +Step 9/14 : RUN go build -o main $MAIN_FILE_PATH + ---> Using cache + ---> 2f5d86796704 +Step 10/14 : RUN chmod +x main + ---> Using cache + ---> 67bff6d26489 + +Step 11/14 : FROM scratch + ---> +Step 12/14 : COPY --from=builder /build/main / + ---> Using cache + ---> e20e97826935 +Step 13/14 : EXPOSE 8081 + ---> Using cache + ---> dcd21bfb36cc +Step 14/14 : ENTRYPOINT ["/main"] + ---> Using cache + ---> e8c54c1c3744 + +Successfully built e8c54c1c3744 +Successfully tagged deployments_calendar_scheduler:latest +Creating deployments_queue_1 ... done +Creating deployments_db_1 ... done +Creating deployments_calendar_1 ... done +Creating deployments_migrator_1 ... done +Creating deployments_calendar_scheduler_1 ... done +Creating deployments_calendar_sender_1 ... done +Running Suite: Tests Suite +========================== +Random Seed: 1600038253 +Will run 8 of 8 specs + +••••••• +------------------------------ +• [SLOW TEST:10.014 seconds] +Sender +/Users/gremlin/education/otus/golang/otus-go/otus-golang-hw/hw12_13_14_15_calendar/integration-tests/sender_test.go:12 + Event + /Users/gremlin/education/otus/golang/otus-go/otus-golang-hw/hw12_13_14_15_calendar/integration-tests/sender_test.go:13 + should receive event + /Users/gremlin/education/otus/golang/otus-go/otus-golang-hw/hw12_13_14_15_calendar/integration-tests/sender_test.go:14 +------------------------------ + +Ran 8 of 8 Specs in 10.205 seconds +SUCCESS! -- 8 Passed | 0 Failed | 0 Pending | 0 Skipped +PASS + +Ginkgo ran 1 suite in 11.265731675s +Test Suite Passed +WARNING: The POSTGRES_USER variable is not set. Defaulting to a blank string. +Stopping deployments_calendar_sender_1 ... done +Stopping deployments_calendar_scheduler_1 ... done +Stopping deployments_calendar_1 ... done +Stopping deployments_db_1 ... done +Stopping deployments_queue_1 ... done +Removing deployments_calendar_sender_1 ... done +Removing deployments_calendar_scheduler_1 ... done +Removing deployments_migrator_1 ... done +Removing deployments_calendar_1 ... done +Removing deployments_db_1 ... done +Removing deployments_queue_1 ... done +Removing network deployments_default \ No newline at end of file diff --git a/hw12_13_14_15_calendar/integration-tests/calendar_test.go b/hw12_13_14_15_calendar/integration-tests/calendar_test.go new file mode 100644 index 0000000..8782fee --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests/calendar_test.go @@ -0,0 +1,159 @@ +package integration + +import ( + "fmt" + "net/http" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var ( + now = time.Now() + day = time.Duration(time.Hour * 24) + week = 7 * time.Duration(day) + month = 30 * time.Duration(day) +) + +func createEvent(title string, startDate time.Time, duration time.Duration) (int, Event, error) { + payload := Event{ + Title: title, + UserID: user.ID, + StartDate: startDate, + EndDate: startDate.Add(duration), + NotifiedFor: 1, + } + return ProcessEvent(EventsURL, http.MethodPost, payload) +} + +var _ = Describe("Calendar", func() { + Describe("Event", func() { + It("should create event", func() { + title := "Test Event" + statusCode, event, err := createEvent(title, now.Add(month), time.Hour) + + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + Expect(event.ID).NotTo(Equal(0)) + Expect(event.UserID).To(Equal(user.ID)) + Expect(event.Title).To(Equal(title)) + }) + + It("should not create event with empty title", func() { + startDate := now.Add(month) + payload := Event{ + Title: "", + UserID: user.ID, + StartDate: startDate, + EndDate: startDate.Add(time.Hour), + NotifiedFor: 1, + } + statusCode, result, err := ProcessError(EventsURL, http.MethodPost, payload) + + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(400)) + Expect(result.Error).To(ContainSubstring("Field validation for 'Title' failed")) + }) + + It("should update event", func() { + _, baseEvent, _ := createEvent("Test Event", now.Add(month), time.Hour) + + updatedTitle := "Updated title" + payload := UpdateEventPayload{ + Event: Event{ + Title: updatedTitle, + }, + } + + statusCode, event, err := ProcessEvent(fmt.Sprintf("%s/%d", EventsURL, baseEvent.ID), http.MethodPut, payload) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + Expect(event.ID).To(Equal(baseEvent.ID)) + Expect(event.UserID).To(Equal(user.ID)) + Expect(event.Title).To(Equal(updatedTitle)) + }) + + It("should remove event", func() { + _, baseEvent, _ := createEvent("Test Event", now.Add(month), time.Hour) + + period := baseEvent.StartDate.Unix() + statusCode, result, err := ProcessEvents(fmt.Sprintf("%s/1/%d", EventsURL, period), http.MethodGet, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + Expect(result.Events).To(ContainElement(baseEvent)) + + statusCode, _, err = ProcessEvent(fmt.Sprintf("%s/%d", EventsURL, baseEvent.ID), http.MethodDelete, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + + statusCode, result, err = ProcessEvents(fmt.Sprintf("%s/1/%d", EventsURL, period), http.MethodGet, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + Expect(result.Events).NotTo(ContainElement(baseEvent)) + }) + + Context("Get events", func() { + It("should get events per day", func() { + startDate := now.Add(month) + + _, evt1, _ := createEvent("Test Event", startDate.Add(-2*day), day) + _, evt2, _ := createEvent("Test Event", startDate.Add(-2*day), 15*day) + _, evt3, _ := createEvent("Test Event", startDate, 15*day) + _, evt4, _ := createEvent("Test Event", startDate.Add(15*day), month) + + statusCode, result, err := ProcessEvents(fmt.Sprintf("%s/1/%d", EventsURL, startDate.Unix()), http.MethodGet, nil) + + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + + Expect(result.Events).NotTo(ContainElement(evt1)) + Expect(result.Events).To(ContainElement(evt2)) + Expect(result.Events).To(ContainElement(evt3)) + Expect(result.Events).NotTo(ContainElement(evt4)) + }) + + It("should get events per week", func() { + startDate := now.Add(month) + + _, evt1, _ := createEvent("Test Event", startDate.Add(-2*day), day) + _, evt2, _ := createEvent("Test Event", startDate.Add(-2*day), 15*day) + _, evt3, _ := createEvent("Test Event", startDate.Add(1*day), day) + _, evt4, _ := createEvent("Test Event", startDate.Add(1*day), 15*day) + _, evt5, _ := createEvent("Test Event", startDate.Add(15*day), day) + + statusCode, result, err := ProcessEvents(fmt.Sprintf("%s/2/%d", EventsURL, startDate.Unix()), http.MethodGet, nil) + + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + + Expect(result.Events).NotTo(ContainElement(evt1)) + Expect(result.Events).To(ContainElement(evt2)) + Expect(result.Events).To(ContainElement(evt3)) + Expect(result.Events).To(ContainElement(evt4)) + Expect(result.Events).NotTo(ContainElement(evt5)) + }) + + It("should get events per month", func() { + startDate := now.Add(month) + + _, evt1, _ := createEvent("Test Event", startDate.Add(-2*day), day) + _, evt2, _ := createEvent("Test Event", startDate.Add(-2*day), 15*day) + _, evt3, _ := createEvent("Test Event", startDate.Add(1*day), day) + _, evt4, _ := createEvent("Test Event", startDate.Add(day+week), day) + _, evt5, _ := createEvent("Test Event", startDate.Add(month+month), day) + + statusCode, result, err := ProcessEvents(fmt.Sprintf("%s/3/%d", EventsURL, startDate.Unix()), http.MethodGet, nil) + + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + + Expect(result.Events).NotTo(ContainElement(evt1)) + Expect(result.Events).To(ContainElement(evt2)) + Expect(result.Events).To(ContainElement(evt3)) + Expect(result.Events).To(ContainElement(evt4)) + Expect(result.Events).NotTo(ContainElement(evt5)) + }) + }) + }) +}) diff --git a/hw12_13_14_15_calendar/integration-tests/helpers.go b/hw12_13_14_15_calendar/integration-tests/helpers.go new file mode 100644 index 0000000..7dde3ba --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests/helpers.go @@ -0,0 +1,91 @@ +package integration + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" +) + +var ( + EventsURL string + UsersURL string +) + +func init() { + apiHost, ok := os.LookupEnv("API_HOST") + + if !ok { + fmt.Fprintf(os.Stderr, "API_HOST is not defined") + os.Exit(1) + } + + EventsURL = fmt.Sprintf("%s/events", apiHost) + UsersURL = fmt.Sprintf("%s/users", apiHost) +} + +func makeRequest(url string, method string, body io.Reader) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(context.Background(), method, url, body) + if err != nil { + return + } + req.Header.Add("Content-type", "application/json") + return http.DefaultClient.Do(req) +} + +func PrepareItem(url, method string, payload interface{}) (statusCode int, content []byte, err error) { + bts, err := json.Marshal(payload) + if err != nil { + return + } + // fmt.Printf("Request to %s %s\n", url, string(bts)) + resp, err := makeRequest(url, method, bytes.NewReader(bts)) + if err != nil { + return + } + defer resp.Body.Close() + statusCode = resp.StatusCode + content, err = ioutil.ReadAll(resp.Body) + // fmt.Printf("Response %s\n", string(content)) + return +} + +func CreateUser(url string, payload User) (statusCode int, result User, err error) { + statusCode, content, err := PrepareItem(url, http.MethodPost, payload) + if err != nil { + return + } + err = json.Unmarshal(content, &result) + return +} + +func ProcessEvent(url, method string, payload interface{}) (statusCode int, result Event, err error) { + statusCode, content, err := PrepareItem(url, method, payload) + if err != nil { + return + } + err = json.Unmarshal(content, &result) + return +} + +func ProcessEvents(url, method string, payload interface{}) (statusCode int, result QueryEventsResponse, err error) { + statusCode, content, err := PrepareItem(url, method, payload) + if err != nil { + return + } + err = json.Unmarshal(content, &result) + return +} + +func ProcessError(url, method string, payload interface{}) (statusCode int, result ErrorResponse, err error) { + statusCode, content, err := PrepareItem(url, method, payload) + if err != nil { + return + } + err = json.Unmarshal(content, &result) + return +} diff --git a/hw12_13_14_15_calendar/integration-tests/init_test.go b/hw12_13_14_15_calendar/integration-tests/init_test.go new file mode 100644 index 0000000..a35e97f --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests/init_test.go @@ -0,0 +1,21 @@ +package integration + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var user User + +var _ = BeforeSuite(func() { + var statusCode int + var err error + statusCode, user, err = CreateUser(UsersURL, User{ + Email: "test@test.com", + FirstName: "Tom", + LastName: "Smith", + }) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + Expect(user.ID).NotTo(Equal(0)) +}) diff --git a/hw12_13_14_15_calendar/integration-tests/models.go b/hw12_13_14_15_calendar/integration-tests/models.go new file mode 100644 index 0000000..b770186 --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests/models.go @@ -0,0 +1,37 @@ +package integration + +import ( + "time" +) + +type User struct { + ID int64 + Email string + FirstName string + LastName string +} + +type Event struct { + ID int64 + UserID int64 + Title string + Status string + Description string + StartDate time.Time + EndDate time.Time + NotifiedFor int64 +} + +type ErrorResponse struct { + Error string `json:"error"` + Code int `json:"code"` + Message string `json:"message"` +} + +type UpdateEventPayload struct { + Event Event `json:"event"` +} + +type QueryEventsResponse struct { + Events []Event `json:"events"` +} diff --git a/hw12_13_14_15_calendar/integration-tests/sender_test.go b/hw12_13_14_15_calendar/integration-tests/sender_test.go new file mode 100644 index 0000000..97e171f --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests/sender_test.go @@ -0,0 +1,44 @@ +package integration + +import ( + "fmt" + "net/http" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Sender", func() { + Describe("Event", func() { + It("should receive event", func() { + startDate := time.Now() + title := fmt.Sprintf("Test Send Event %d", startDate.Unix()) + payload := Event{ + Title: title, + Description: "Test description", + UserID: user.ID, + StartDate: startDate, + EndDate: startDate.Add(time.Hour), + NotifiedFor: 1, + } + statusCode, event, err := ProcessEvent(EventsURL, http.MethodPost, payload) + + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + Expect(user.ID).To(Equal(user.ID)) + Expect(event.Title).To(Equal(title)) + Expect(event.Status).To(Equal("New")) + + // waiting for event processing + time.Sleep(time.Duration(10 * time.Second)) + + statusCode, result, err := ProcessEvents(fmt.Sprintf("%s/1/%d", EventsURL, startDate.Unix()), http.MethodGet, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(200)) + + event.Status = "Sent" + Expect(result.Events).To(ContainElement(event)) + }) + }) +}) diff --git a/hw12_13_14_15_calendar/integration-tests/tests_suite_test.go b/hw12_13_14_15_calendar/integration-tests/tests_suite_test.go new file mode 100644 index 0000000..b28c21f --- /dev/null +++ b/hw12_13_14_15_calendar/integration-tests/tests_suite_test.go @@ -0,0 +1,13 @@ +package integration + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestTestsGink(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Tests Suite") +} diff --git a/hw12_13_14_15_calendar/internal/config/config.go b/hw12_13_14_15_calendar/internal/config/config.go index a549414..c250252 100644 --- a/hw12_13_14_15_calendar/internal/config/config.go +++ b/hw12_13_14_15_calendar/internal/config/config.go @@ -1,84 +1,48 @@ package config import ( - "context" - "errors" - - "github.com/heetch/confita" - "github.com/heetch/confita/backend/env" - "github.com/heetch/confita/backend/file" + "github.com/ilyakaznacheev/cleanenv" ) type Calendar struct { - Host string `yaml:"host" config:"required"` - Port int `yaml:"port" config:"required"` - GRPCAddress string `yaml:"grpcAddress"` - HTTPAddress string `yaml:"httpAddress"` + Host string `yaml:"host" env:"HOST" env-default:"localhost"` + Port int `yaml:"port" env:"PORT" env-default:"8081"` + GRPCAddress string `yaml:"grpcAddress" env:"GRPC_ADDRESS"` + HTTPAddress string `yaml:"httpAddress" env:"HTTP_ADDRESS"` LogConfig LogConfig `yaml:"logConfig"` DBConfig DBConfig `yaml:"dbConfig"` } type Scheduler struct { - LogConfig LogConfig `yaml:"logConfig"` - DBConfig DBConfig `yaml:"dbConfig"` - QueueConfig QueueConfig `yaml:"queueConfig"` + LogConfig LogConfig + DBConfig DBConfig + QueueConfig QueueConfig } type Sender struct { - LogConfig LogConfig `yaml:"logConfig"` - DBConfig DBConfig `yaml:"dbConfig"` - QueueConfig QueueConfig `yaml:"queueConfig"` + LogConfig LogConfig + DBConfig DBConfig + QueueConfig QueueConfig } -var ErrConfigPath = errors.New("config path is not provided") - -func NewCalendar(fpath string) (config *Calendar, err error) { - if fpath == "" { - return nil, ErrConfigPath - } - config = &Calendar{ - Host: "localhost", - Port: 8081, - LogConfig: defaultLogConfig(), - DBConfig: defaultDBConfig(), +func readConfig(fpath string, cfg interface{}) error { + if fpath != "" { + return cleanenv.ReadConfig(fpath, cfg) } - loader := confita.NewLoader( - file.NewBackend(fpath), - env.NewBackend(), - ) - err = loader.Load(context.Background(), config) - return + return cleanenv.ReadEnv(cfg) } -func NewScheduler(fpath string) (config *Scheduler, err error) { - if fpath == "" { - return nil, ErrConfigPath - } - config = &Scheduler{ - LogConfig: defaultLogConfig(), - DBConfig: defaultDBConfig(), - QueueConfig: defaultQueueConfig(), - } - loader := confita.NewLoader( - file.NewBackend(fpath), - env.NewBackend(), - ) - err = loader.Load(context.Background(), config) - return +func NewCalendar(fpath string) (*Calendar, error) { + var cfg Calendar + return &cfg, readConfig(fpath, &cfg) } -func NewSender(fpath string) (config *Sender, err error) { - if fpath == "" { - return nil, ErrConfigPath - } - config = &Sender{ - LogConfig: defaultLogConfig(), - QueueConfig: defaultQueueConfig(), - } - loader := confita.NewLoader( - file.NewBackend(fpath), - env.NewBackend(), - ) - err = loader.Load(context.Background(), config) - return +func NewScheduler(fpath string) (*Scheduler, error) { + var cfg Scheduler + return &cfg, readConfig(fpath, &cfg) +} + +func NewSender(fpath string) (*Sender, error) { + var cfg Sender + return &cfg, readConfig(fpath, &cfg) } diff --git a/hw12_13_14_15_calendar/internal/config/db_config.go b/hw12_13_14_15_calendar/internal/config/db_config.go index b2986c5..c13df76 100644 --- a/hw12_13_14_15_calendar/internal/config/db_config.go +++ b/hw12_13_14_15_calendar/internal/config/db_config.go @@ -1,21 +1,12 @@ package config type DBConfig struct { - Host string `yaml:"host" config:"required"` - Port int `yaml:"port" config:"required"` - DBName string `yaml:"dbName" config:"required"` - User string `yaml:"user" config:"required"` - Pass string `yaml:"pass" config:"required"` - MaxConn int `yaml:"maxConn" config:"required"` - ItemsPerQuery int `yaml:"itemsPerQuery" config:"required"` - RepoType string `yaml:"repoType" config:"required"` -} - -func defaultDBConfig() DBConfig { - return DBConfig{ - Host: "localhost", - Port: 5432, - MaxConn: 10, - ItemsPerQuery: 100, - } + Host string `yaml:"host" env:"DB_HOST"` + Port int `yaml:"port" env:"DB_PORT"` + User string `yaml:"user" env:"DB_USER"` + Password string `yaml:"password" env:"DB_PASSWORD"` + DBName string `yaml:"dbName" env:"DB_NAME"` + MaxConn int `yaml:"maxConn" env:"DB_MAX_CONN" env-default:"10"` + ItemsPerQuery int `yaml:"itemsPerQuery" env:"DB_ITEMS_PER_QUERY" env-default:"100"` + RepoType string `yaml:"repoType" env:"DB_REPO_TYPE"` } diff --git a/hw12_13_14_15_calendar/internal/config/log_config.go b/hw12_13_14_15_calendar/internal/config/log_config.go index 911fa17..f7d338a 100644 --- a/hw12_13_14_15_calendar/internal/config/log_config.go +++ b/hw12_13_14_15_calendar/internal/config/log_config.go @@ -1,12 +1,6 @@ package config type LogConfig struct { - Level string `yaml:"level"` - FilePath string `yaml:"filePath"` -} - -func defaultLogConfig() LogConfig { - return LogConfig{ - Level: "info", - } + Level string `yaml:"level" env:"LOG_LEVEL" env-default:"info"` + FilePath string `yaml:"filePath" env:"LOG_FILE"` } diff --git a/hw12_13_14_15_calendar/internal/config/queue_config.go b/hw12_13_14_15_calendar/internal/config/queue_config.go index 47d12d4..19c8525 100644 --- a/hw12_13_14_15_calendar/internal/config/queue_config.go +++ b/hw12_13_14_15_calendar/internal/config/queue_config.go @@ -1,27 +1,11 @@ package config type QueueConfig struct { - Host string `yaml:"host" config:"required"` - Port int `yaml:"port" config:"required"` - User string `yaml:"user" config:"required"` - Pass string `yaml:"pass" config:"required"` - QueueName string `yaml:"queueName" config:"required"` - ExchangeType string `yaml:"exchangeType" config:"required"` - ScanTimeoutMs int `yaml:"scanTimeoutMs" config:"required"` - QosPrefetchCount int `yaml:"qosPrefetchCount" config:"required"` - MaxReconnectAttempts int `yaml:"maxReconnectAttempts" config:"required"` - ReconnectTimeoutMs int -} - -func defaultQueueConfig() QueueConfig { - return QueueConfig{ - Host: "localhost", - Port: 5672, - QueueName: "events", - ExchangeType: "direct", - ScanTimeoutMs: 10000, - QosPrefetchCount: 50, - MaxReconnectAttempts: 5, - ReconnectTimeoutMs: 2000, - } + URI string `yaml:"uri" env:"QUEUE_URI"` + QueueName string `yaml:"queueName" env:"QUEUE_NAME" env-default:"events"` + ExchangeType string `yaml:"exchangeType" env:"QUEUE_EXCHANGE_TYPE" env-default:"direct"` + ScanTimeoutMs int `yaml:"scanTimeoutMs" env:"QUEUE_SCAN_TIMEOUT_MS" env-default:"10000"` + QosPrefetchCount int `yaml:"qosPrefetchCount" env:"QUEUE_QOS_PREFETCH_COUNT" env-default:"50"` + MaxReconnectAttempts int `yaml:"maxReconnectAttempts" env:"QUEUE_MAC_RECONNECT_ATTEMPTS" env-default:"5"` + ReconnectTimeoutMs int `yaml:"reconnectTimeoutMs" env:"QUEUE_MAC_RECONNECT_TIMEOUT_MS" env-default:"2000"` } diff --git a/hw12_13_14_15_calendar/internal/queue/consumer.go b/hw12_13_14_15_calendar/internal/queue/consumer.go index 14a0110..b548f87 100644 --- a/hw12_13_14_15_calendar/internal/queue/consumer.go +++ b/hw12_13_14_15_calendar/internal/queue/consumer.go @@ -62,7 +62,7 @@ func (c *Consumer) Reconnect() (deliveries <-chan amqp.Delivery, err error) { return } -func (c *Consumer) Handle(fn func([]byte)) error { +func (c *Consumer) Handle(fn func([]byte) error) error { if err := c.Connect(); err != nil { return err } @@ -74,7 +74,10 @@ func (c *Consumer) Handle(fn func([]byte)) error { select { case msg := <-deliveries: log.Debug().Msgf("Receiving events from queue: %+v", msg.Body) - fn(msg.Body) + err := fn(msg.Body) + if err != nil { + log.Error().Msgf("Processing event: %s", err) + } case <-c.connector.errCh: deliveries, err = c.Reconnect() if err != nil { diff --git a/hw12_13_14_15_calendar/internal/repository/errors.go b/hw12_13_14_15_calendar/internal/repository/errors.go index 2379efb..ed327dd 100644 --- a/hw12_13_14_15_calendar/internal/repository/errors.go +++ b/hw12_13_14_15_calendar/internal/repository/errors.go @@ -6,9 +6,10 @@ import ( var ( ErrConfigInvalid = errors.New("provided config is invalid") - ErrEventNotFound = errors.New("event not found") + ErrItemNotFound = errors.New("item not found") ErrEventValidation = errors.New("validation error") ErrEventCreate = errors.New("error happened during creating the event") ErrEventUpdate = errors.New("error happened during updating the event") ErrEventDelete = errors.New("error happened during removing the event") + ErrUserCreate = errors.New("error happened during creating the user") ) diff --git a/hw12_13_14_15_calendar/internal/repository/memory.go b/hw12_13_14_15_calendar/internal/repository/memory.go index ba09852..1e3b9aa 100644 --- a/hw12_13_14_15_calendar/internal/repository/memory.go +++ b/hw12_13_14_15_calendar/internal/repository/memory.go @@ -8,11 +8,15 @@ import ( "github.com/dmitryt/otus-golang-hw/hw12_13_14_15_calendar/internal/utils" ) -type MemoryStorage map[int64]Event +type ( + MemoryStorageEvents map[int64]Event + MemoryStorageUsers map[int64]User +) type MemoryRepo struct { - storage MemoryStorage - mx sync.RWMutex + events MemoryStorageEvents + users MemoryStorageUsers + mx sync.RWMutex } func (r *MemoryRepo) Connect(ctx context.Context, url string) error { @@ -25,15 +29,23 @@ func (r *MemoryRepo) Close() error { } func (r *MemoryRepo) ClearStorage() { - r.storage = make(MemoryStorage) + r.events = make(MemoryStorageEvents) + r.users = make(MemoryStorageUsers) +} + +func (r *MemoryRepo) GetStorageEvents() *MemoryStorageEvents { + return &r.events } -func (r *MemoryRepo) GetStorage() *MemoryStorage { - return &r.storage +func (r *MemoryRepo) GetStorageUsers() *MemoryStorageUsers { + return &r.users } func NewMemoryRepo() *MemoryRepo { - return &MemoryRepo{storage: make(MemoryStorage)} + return &MemoryRepo{ + events: make(MemoryStorageEvents), + users: make(MemoryStorageUsers), + } } func isDateAfter(date time.Time, base time.Time) bool { @@ -48,7 +60,7 @@ func (r *MemoryRepo) getEventsInRange(startPeriod time.Time, endPeriod time.Time r.mx.RLock() defer r.mx.RUnlock() result := []Event{} - for _, v := range r.storage { + for _, v := range r.events { isStartPeriodInRange := isDateAfter(startPeriod, v.StartDate) && isDateBefore(startPeriod, v.EndDate) isEndPeriodInRange := isDateAfter(endPeriod, v.StartDate) && isDateBefore(endPeriod, v.EndDate) isPeriodOutRange := isDateAfter(endPeriod, v.EndDate) && isDateBefore(startPeriod, v.StartDate) @@ -80,30 +92,30 @@ func (r *MemoryRepo) CreateEvent(data Event) (Event, error) { data.ID = id r.mx.Lock() defer r.mx.Unlock() - r.storage[id] = data + r.events[id] = data return data, nil } func (r *MemoryRepo) UpdateEvent(id int64, data Event) (event Event, err error) { r.mx.Lock() defer r.mx.Unlock() - event, ok := r.storage[id] + event, ok := r.events[id] if !ok { - return Event{}, ErrEventNotFound + return Event{}, ErrItemNotFound } err = MergeEvents(&event, data) - r.storage[id] = event + r.events[id] = event return } func (r *MemoryRepo) DeleteEvent(id int64) (err error) { r.mx.Lock() defer r.mx.Unlock() - _, ok := r.storage[id] + _, ok := r.events[id] if !ok { - return ErrEventNotFound + return ErrItemNotFound } - delete(r.storage, id) + delete(r.events, id) return } @@ -118,3 +130,25 @@ func (r *MemoryRepo) MarkEventsAsSent(ids *[]int64) error { func (r *MemoryRepo) MarkEventsAsProcessed(ids *[]int64) error { return nil } + +func (r *MemoryRepo) CreateUser(data User) (User, error) { + id, err := utils.GenerateUID() + if err != nil { + return User{}, ErrUserCreate + } + data.ID = id + r.mx.Lock() + defer r.mx.Unlock() + r.users[id] = data + return data, nil +} + +func (r *MemoryRepo) GetUser(id int64) (User, error) { + r.mx.Lock() + defer r.mx.Unlock() + user, ok := r.users[id] + if !ok { + return User{}, ErrItemNotFound + } + return user, nil +} diff --git a/hw12_13_14_15_calendar/internal/repository/memory_test.go b/hw12_13_14_15_calendar/internal/repository/memory_test.go index d659d78..8a572b3 100644 --- a/hw12_13_14_15_calendar/internal/repository/memory_test.go +++ b/hw12_13_14_15_calendar/internal/repository/memory_test.go @@ -21,15 +21,15 @@ func TestMemoryRepo(t *testing.T) { t.Run("get day events", func(t *testing.T) { r := NewMemoryRepo() - r.storage[1] = Event{ID: 1, UserID: 1, StartDate: getDate(1, time.November), EndDate: getDate(2, time.November)} - r.storage[2] = Event{ID: 2, UserID: 1, StartDate: getDate(1, time.November), EndDate: getDate(15, time.November)} - r.storage[3] = Event{ID: 3, UserID: 1, StartDate: getDate(3, time.November), EndDate: getDate(4, time.November)} - r.storage[4] = Event{ID: 4, UserID: 1, StartDate: getDate(15, time.November), EndDate: getDate(16, time.November)} + r.events[1] = Event{ID: 1, UserID: 1, StartDate: getDate(1, time.November), EndDate: getDate(2, time.November)} + r.events[2] = Event{ID: 2, UserID: 1, StartDate: getDate(1, time.November), EndDate: getDate(15, time.November)} + r.events[3] = Event{ID: 3, UserID: 1, StartDate: getDate(3, time.November), EndDate: getDate(4, time.November)} + r.events[4] = Event{ID: 4, UserID: 1, StartDate: getDate(15, time.November), EndDate: getDate(16, time.November)} result, err := r.GetDayEvents(getDate(3, time.November)) require.Nil(t, err) - require.Equal(t, result, []Event{r.storage[2], r.storage[3]}) + require.Equal(t, result, []Event{r.events[2], r.events[3]}) }) t.Run("get week events", func(t *testing.T) { @@ -45,21 +45,21 @@ func TestMemoryRepo(t *testing.T) { date25_11 := getDate(25, time.November) // before requested week - r.storage[1] = Event{ID: 1, UserID: 1, StartDate: date01_10, EndDate: date01_11} + r.events[1] = Event{ID: 1, UserID: 1, StartDate: date01_10, EndDate: date01_11} // starts before requested week - r.storage[2] = Event{ID: 2, UserID: 1, StartDate: date01_10, EndDate: date02_11} + r.events[2] = Event{ID: 2, UserID: 1, StartDate: date01_10, EndDate: date02_11} // starts and ends within requested week - r.storage[3] = Event{ID: 3, UserID: 1, StartDate: date03_11, EndDate: date05_11} + r.events[3] = Event{ID: 3, UserID: 1, StartDate: date03_11, EndDate: date05_11} // starts within requested week and ends after it - r.storage[4] = Event{ID: 4, UserID: 1, StartDate: date05_11, EndDate: date15_11} + r.events[4] = Event{ID: 4, UserID: 1, StartDate: date05_11, EndDate: date15_11} // starts and ends after requested week - r.storage[5] = Event{ID: 5, UserID: 1, StartDate: date15_11, EndDate: date25_11} + r.events[5] = Event{ID: 5, UserID: 1, StartDate: date15_11, EndDate: date25_11} result, err := r.GetWeekEvents(date02_11) require.Nil(t, err) fmt.Printf("%+v", result) - require.ElementsMatch(t, []Event{r.storage[2], r.storage[3], r.storage[4]}, result) + require.ElementsMatch(t, []Event{r.events[2], r.events[3], r.events[4]}, result) }) t.Run("get month events", func(t *testing.T) { @@ -77,22 +77,22 @@ func TestMemoryRepo(t *testing.T) { date15_12 := getDate(15, time.December) // before requested month - r.storage[1] = Event{ID: 1, UserID: 1, StartDate: date01_10, EndDate: date02_10} + r.events[1] = Event{ID: 1, UserID: 1, StartDate: date01_10, EndDate: date02_10} // starts before requested month - r.storage[2] = Event{ID: 2, UserID: 1, StartDate: date01_10, EndDate: date01_11} + r.events[2] = Event{ID: 2, UserID: 1, StartDate: date01_10, EndDate: date01_11} // starts and ends within requested month - r.storage[3] = Event{ID: 3, UserID: 1, StartDate: date02_11, EndDate: date03_11} + r.events[3] = Event{ID: 3, UserID: 1, StartDate: date02_11, EndDate: date03_11} // starts within requested month and ends after it - r.storage[4] = Event{ID: 4, UserID: 1, StartDate: date05_11, EndDate: date2_12} + r.events[4] = Event{ID: 4, UserID: 1, StartDate: date05_11, EndDate: date2_12} // starts and ends after requested month - r.storage[5] = Event{ID: 5, UserID: 1, StartDate: date2_12, EndDate: date15_12} + r.events[5] = Event{ID: 5, UserID: 1, StartDate: date2_12, EndDate: date15_12} result, err := r.GetMonthEvents(date01_11) require.Nil(t, err) fmt.Printf("%+v", result) - require.ElementsMatch(t, []Event{r.storage[2], r.storage[3], r.storage[4]}, result) + require.ElementsMatch(t, []Event{r.events[2], r.events[3], r.events[4]}, result) }) t.Run("create event", func(t *testing.T) { @@ -103,32 +103,32 @@ func TestMemoryRepo(t *testing.T) { event, err := r.CreateEvent(Event{UserID: 1, StartDate: startDate, EndDate: endDate}) require.Nil(t, err) require.NotNil(t, event) - require.Equal(t, event, r.storage[event.ID]) + require.Equal(t, event, r.events[event.ID]) }) t.Run("update event", func(t *testing.T) { r := NewMemoryRepo() var id int64 = 1 startDate := getDate(10, time.October) - r.storage[id] = Event{UserID: 1, StartDate: startDate} + r.events[id] = Event{UserID: 1, StartDate: startDate} endDate := startDate.AddDate(0, 0, 1) event, err := r.UpdateEvent(id, Event{UserID: 1, EndDate: endDate}) require.Nil(t, err) - require.Equal(t, event, r.storage[id]) + require.Equal(t, event, r.events[id]) }) t.Run("remove event", func(t *testing.T) { r := NewMemoryRepo() var id int64 = 1 startDate := getDate(10, time.October) - r.storage[id] = Event{UserID: 1, StartDate: startDate} + r.events[id] = Event{UserID: 1, StartDate: startDate} err := r.DeleteEvent(id) require.Nil(t, err) - _, ok := r.storage[id] + _, ok := r.events[id] require.False(t, ok) }) @@ -136,10 +136,10 @@ func TestMemoryRepo(t *testing.T) { r := NewMemoryRepo() var id int64 = 1 startDate := getDate(10, time.October) - r.storage[id] = Event{UserID: 1, StartDate: startDate} + r.events[id] = Event{UserID: 1, StartDate: startDate} err := r.DeleteEvent(111) - require.EqualError(t, err, fmt.Sprintf("%s", ErrEventNotFound)) + require.EqualError(t, err, fmt.Sprintf("%s", ErrItemNotFound)) }) } diff --git a/hw12_13_14_15_calendar/internal/repository/psql.go b/hw12_13_14_15_calendar/internal/repository/psql.go index caa6c7c..2b757c6 100644 --- a/hw12_13_14_15_calendar/internal/repository/psql.go +++ b/hw12_13_14_15_calendar/internal/repository/psql.go @@ -35,6 +35,8 @@ VALUES (:user_id, :title, :description, :start_date, :end_date, :notified_for) RETURNING id` +var insertUserQs = `INSERT INTO users (email, first_name, last_name) VALUES (:email, :first_name, :last_name) RETURNING id` + var insertStatusQs = `INSERT INTO events_status (event_id) VALUES ($1)` var updateQs = `UPDATE events @@ -82,17 +84,28 @@ func NewPSQLRepo(args ...interface{}) *PSQLRepo { } func (r *PSQLRepo) getEventsBetween(startPeriod time.Time, endPeriod time.Time) (result []Event, err error) { - query := "SELECT * FROM events WHERE (start_date <= $1 and end_date >= $1) or (start_date <= $2 and end_date >= $2) or (start_date >= $1 and end_date <= $2) ORDER BY start_date ASC LIMIT $3" + query := `SELECT e.*, es.status FROM events e JOIN events_status es on e.id = es.event_id + WHERE (start_date <= $1 and end_date >= $1) or (start_date <= $2 and end_date >= $2) or (start_date >= $1 and end_date <= $2) ORDER BY start_date ASC LIMIT $3` err = r.db.Select(&result, query, startPeriod, endPeriod, r.itemsPerQuery) return } -func (r *PSQLRepo) getEventByID(id int64) (result Event, err error) { - err = r.db.Get(&result, "SELECT * FROM events WHERE id = $1", id) +func (r *PSQLRepo) getEventByID(id int64) (Event, error) { + event := Event{} + err := r.db.Get(&event, "SELECT e.*, es.status FROM events e join events_status es on e.id = es.event_id WHERE e.id = $1", id) if err != nil { - log.Debug().Msgf("[DB] getEventByID Err %d, %+v, %s", id, result, err) + log.Debug().Msgf("[DB] getEventByID Err %d, %+v, %s", id, event, err) } - return + return event, err +} + +func (r *PSQLRepo) getUserByID(id int64) (User, error) { + user := User{} + err := r.db.Get(&user, "SELECT * FROM users WHERE id = $1", id) + if err != nil { + log.Debug().Msgf("[DB] getUserByID Err %d, %+v, %s", id, user, err) + } + return user, err } func (r *PSQLRepo) GetDayEvents(date time.Time) (result []Event, err error) { @@ -158,7 +171,7 @@ func (r *PSQLRepo) CreateEvent(data Event) (event Event, err error) { } if evt.ID == 0 { - err = ErrEventNotFound + err = ErrItemNotFound return } _, err = tx.Exec(insertStatusQs, evt.ID) @@ -201,6 +214,38 @@ func (r *PSQLRepo) UpdateEvent(id int64, data Event) (event Event, err error) { return r.getEventByID(id) } +func (r *PSQLRepo) CreateUser(data User) (user User, err error) { + err = r.validator.Struct(data) + if err != nil { + return + } + stmt, err := r.db.PrepareNamed(insertUserQs) + if err != nil { + return + } + + row := stmt.QueryRow(data) + if err = row.Err(); err != nil { + return + } + usr := User{} + err = row.StructScan(&usr) + if err != nil { + return + } + + if usr.ID == 0 { + err = ErrItemNotFound + return + } + + return r.getUserByID(usr.ID) +} + +func (r *PSQLRepo) GetUser(id int64) (user User, err error) { + return r.getUserByID(id) +} + func (r *PSQLRepo) GetCurrentEvents() (result []Event, err error) { err = r.db.Select(&result, selectCurrentEventsQs) return diff --git a/hw12_13_14_15_calendar/internal/repository/repository.go b/hw12_13_14_15_calendar/internal/repository/repository.go index e0e57a4..7878d0b 100644 --- a/hw12_13_14_15_calendar/internal/repository/repository.go +++ b/hw12_13_14_15_calendar/internal/repository/repository.go @@ -25,6 +25,9 @@ type CRUD interface { CreateEvent(Event) (Event, error) UpdateEvent(int64, Event) (Event, error) DeleteEvent(int64) error + + CreateUser(User) (User, error) + GetUser(int64) (User, error) dbConnector } @@ -43,9 +46,17 @@ type Event struct { Description sql.NullString `db:"description"` StartDate time.Time `db:"start_date" validate:"required"` EndDate time.Time `db:"end_date" validate:"required,gtfield=StartDate"` - NotifiedFor int `db:"notified_for" validate:"gte=1"` + NotifiedFor int64 `db:"notified_for" validate:"gte=1"` CreatedAt sql.NullTime `db:"created_at"` UpdatedAt sql.NullTime `db:"updated_at"` + Status string `db:"status"` +} + +type User struct { + ID int64 `db:"id"` + Email string `db:"email" validate:"required,email"` + FirstName sql.NullString `db:"first_name"` + LastName sql.NullString `db:"last_name"` } func newRepo(repoType string, args ...interface{}) interface{} { @@ -75,5 +86,5 @@ func NewStats(repoType string, args ...interface{}) Stats { } func GetSQLDSN(c *config.DBConfig) string { - return fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", c.Host, c.Port, c.DBName, c.User, c.Pass) + return fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", c.Host, c.Port, c.DBName, c.User, c.Password) } diff --git a/hw12_13_14_15_calendar/internal/sender/app.go b/hw12_13_14_15_calendar/internal/sender/app.go index fa24d11..9a9965b 100644 --- a/hw12_13_14_15_calendar/internal/sender/app.go +++ b/hw12_13_14_15_calendar/internal/sender/app.go @@ -11,15 +11,16 @@ import ( ) type App struct { + r repository.Stats c *queue.Consumer scanTimeout int } -func New(c *queue.Consumer, scanTimeout int) *App { - return &App{c: c, scanTimeout: scanTimeout} +func New(r repository.Stats, c *queue.Consumer, scanTimeout int) *App { + return &App{c: c, r: r, scanTimeout: scanTimeout} } -func processEvents(msg []byte) { +func (app *App) processEvents(msg []byte) error { var events []repository.Event err := json.Unmarshal(msg, &events) if err != nil { @@ -28,9 +29,11 @@ func processEvents(msg []byte) { for _, event := range events { fmt.Printf("[SEND] Event %s starts at %s, ends at %s\n", event.Title, event.StartDate.Format(time.RFC3339), event.EndDate.Format(time.RFC3339)) } + return app.r.MarkEventsAsSent(&events) } + return nil } func (app *App) Run() error { - return app.c.Handle(processEvents) + return app.c.Handle(app.processEvents) } diff --git a/hw12_13_14_15_calendar/migrations/20200816153151_init.sql b/hw12_13_14_15_calendar/migrations/001_init_tables.sql similarity index 100% rename from hw12_13_14_15_calendar/migrations/20200816153151_init.sql rename to hw12_13_14_15_calendar/migrations/001_init_tables.sql diff --git a/hw12_13_14_15_calendar/migrations/20200827150345_add_event_status_table.sql b/hw12_13_14_15_calendar/migrations/002_add_event_status_table.sql similarity index 100% rename from hw12_13_14_15_calendar/migrations/20200827150345_add_event_status_table.sql rename to hw12_13_14_15_calendar/migrations/002_add_event_status_table.sql diff --git a/hw12_13_14_15_calendar/node_modules/.yarn-integrity b/hw12_13_14_15_calendar/node_modules/.yarn-integrity deleted file mode 100644 index f41febe..0000000 --- a/hw12_13_14_15_calendar/node_modules/.yarn-integrity +++ /dev/null @@ -1,12 +0,0 @@ -{ - "systemParams": "darwin-x64-72", - "modulesFolders": [], - "flags": [], - "linkedModules": [ - "@adstream/navigation-bar" - ], - "topLevelPatterns": [], - "lockfileEntries": {}, - "files": [], - "artifacts": {} -} \ No newline at end of file diff --git a/hw12_13_14_15_calendar/scripts/migrations.sh b/hw12_13_14_15_calendar/scripts/migrations.sh deleted file mode 100755 index df09348..0000000 --- a/hw12_13_14_15_calendar/scripts/migrations.sh +++ /dev/null @@ -1,27 +0,0 @@ -#/bin/sh - -# source https://www.manongdao.com/article-83733.html -function parse_yaml { - local prefix=$2 - local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034') - sed -ne "s|^\($s\):|\1|" \ - -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \ - -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 | - awk -F$fs '{ - indent = length($1)/2; - vname[indent] = $2; - for (i in vname) {if (i > indent) {delete vname[i]}} - if (length($3) > 0) { - vn=""; for (i=0; i $file -echo "goose -dir ./migrations postgres \"user=\$dbConfig_user password=\$dbConfig_pass dbname=\$dbConfig_dbName sslmode=disable\" up" >> $file -chmod +x $file -sh $file -rm $file \ No newline at end of file diff --git a/hw12_13_14_15_calendar/service/schema/calendar.proto b/hw12_13_14_15_calendar/service/schema/calendar.proto index 483696c..004c016 100644 --- a/hw12_13_14_15_calendar/service/schema/calendar.proto +++ b/hw12_13_14_15_calendar/service/schema/calendar.proto @@ -7,13 +7,21 @@ import "google/api/annotations.proto"; option go_package=".;server"; message Event { - int64 ID = 1; - int64 UserID = 2; + int32 ID = 1; + int32 UserID = 2; string Title = 3; string Description = 4; google.protobuf.Timestamp StartDate = 5; google.protobuf.Timestamp EndDate = 6; - int64 NotifiedFor = 7; + int32 NotifiedFor = 7; + string Status = 8; +} + +message User { + int32 ID = 1; + string Email = 2; + string FirstName = 3; + string LastName = 4; } message EventsResponse { @@ -41,6 +49,10 @@ message DeleteEventRequest { int64 id = 1; } +message GetUserRequest { + int64 id = 1; +} + service Calendar { rpc GetEvents (QueryEventsRequest) returns (EventsResponse) { option (google.api.http) = { @@ -65,4 +77,15 @@ service Calendar { delete: "/events/{id}" }; } + rpc GetUser (GetUserRequest) returns (User) { + option (google.api.http) = { + get: "/users/{id}" + }; + } + rpc CreateUser (User) returns (User) { + option (google.api.http) = { + post: "/users", + body: "*", + }; + } } diff --git a/hw12_13_14_15_calendar/service/server/calendar.pb.go b/hw12_13_14_15_calendar/service/server/calendar.pb.go index e53c6d5..2e2add0 100644 --- a/hw12_13_14_15_calendar/service/server/calendar.pb.go +++ b/hw12_13_14_15_calendar/service/server/calendar.pb.go @@ -90,13 +90,14 @@ type Event struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - UserID int64 `protobuf:"varint,2,opt,name=UserID,proto3" json:"UserID,omitempty"` + ID int32 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + UserID int32 `protobuf:"varint,2,opt,name=UserID,proto3" json:"UserID,omitempty"` Title string `protobuf:"bytes,3,opt,name=Title,proto3" json:"Title,omitempty"` Description string `protobuf:"bytes,4,opt,name=Description,proto3" json:"Description,omitempty"` StartDate *timestamp.Timestamp `protobuf:"bytes,5,opt,name=StartDate,proto3" json:"StartDate,omitempty"` EndDate *timestamp.Timestamp `protobuf:"bytes,6,opt,name=EndDate,proto3" json:"EndDate,omitempty"` - NotifiedFor int64 `protobuf:"varint,7,opt,name=NotifiedFor,proto3" json:"NotifiedFor,omitempty"` + NotifiedFor int32 `protobuf:"varint,7,opt,name=NotifiedFor,proto3" json:"NotifiedFor,omitempty"` + Status string `protobuf:"bytes,8,opt,name=Status,proto3" json:"Status,omitempty"` } func (x *Event) Reset() { @@ -131,14 +132,14 @@ func (*Event) Descriptor() ([]byte, []int) { return file_calendar_proto_rawDescGZIP(), []int{0} } -func (x *Event) GetID() int64 { +func (x *Event) GetID() int32 { if x != nil { return x.ID } return 0 } -func (x *Event) GetUserID() int64 { +func (x *Event) GetUserID() int32 { if x != nil { return x.UserID } @@ -173,13 +174,91 @@ func (x *Event) GetEndDate() *timestamp.Timestamp { return nil } -func (x *Event) GetNotifiedFor() int64 { +func (x *Event) GetNotifiedFor() int32 { if x != nil { return x.NotifiedFor } return 0 } +func (x *Event) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ID int32 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + Email string `protobuf:"bytes,2,opt,name=Email,proto3" json:"Email,omitempty"` + FirstName string `protobuf:"bytes,3,opt,name=FirstName,proto3" json:"FirstName,omitempty"` + LastName string `protobuf:"bytes,4,opt,name=LastName,proto3" json:"LastName,omitempty"` +} + +func (x *User) Reset() { + *x = User{} + if protoimpl.UnsafeEnabled { + mi := &file_calendar_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_calendar_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_calendar_proto_rawDescGZIP(), []int{1} +} + +func (x *User) GetID() int32 { + if x != nil { + return x.ID + } + return 0 +} + +func (x *User) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *User) GetFirstName() string { + if x != nil { + return x.FirstName + } + return "" +} + +func (x *User) GetLastName() string { + if x != nil { + return x.LastName + } + return "" +} + type EventsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -191,7 +270,7 @@ type EventsResponse struct { func (x *EventsResponse) Reset() { *x = EventsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_calendar_proto_msgTypes[1] + mi := &file_calendar_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -204,7 +283,7 @@ func (x *EventsResponse) String() string { func (*EventsResponse) ProtoMessage() {} func (x *EventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_calendar_proto_msgTypes[1] + mi := &file_calendar_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -217,7 +296,7 @@ func (x *EventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EventsResponse.ProtoReflect.Descriptor instead. func (*EventsResponse) Descriptor() ([]byte, []int) { - return file_calendar_proto_rawDescGZIP(), []int{1} + return file_calendar_proto_rawDescGZIP(), []int{2} } func (x *EventsResponse) GetEvents() []*Event { @@ -239,7 +318,7 @@ type QueryEventsRequest struct { func (x *QueryEventsRequest) Reset() { *x = QueryEventsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_calendar_proto_msgTypes[2] + mi := &file_calendar_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -252,7 +331,7 @@ func (x *QueryEventsRequest) String() string { func (*QueryEventsRequest) ProtoMessage() {} func (x *QueryEventsRequest) ProtoReflect() protoreflect.Message { - mi := &file_calendar_proto_msgTypes[2] + mi := &file_calendar_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -265,7 +344,7 @@ func (x *QueryEventsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryEventsRequest.ProtoReflect.Descriptor instead. func (*QueryEventsRequest) Descriptor() ([]byte, []int) { - return file_calendar_proto_rawDescGZIP(), []int{2} + return file_calendar_proto_rawDescGZIP(), []int{3} } func (x *QueryEventsRequest) GetType() QueryRangeType { @@ -294,7 +373,7 @@ type UpdateEventRequest struct { func (x *UpdateEventRequest) Reset() { *x = UpdateEventRequest{} if protoimpl.UnsafeEnabled { - mi := &file_calendar_proto_msgTypes[3] + mi := &file_calendar_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -307,7 +386,7 @@ func (x *UpdateEventRequest) String() string { func (*UpdateEventRequest) ProtoMessage() {} func (x *UpdateEventRequest) ProtoReflect() protoreflect.Message { - mi := &file_calendar_proto_msgTypes[3] + mi := &file_calendar_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -320,7 +399,7 @@ func (x *UpdateEventRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateEventRequest.ProtoReflect.Descriptor instead. func (*UpdateEventRequest) Descriptor() ([]byte, []int) { - return file_calendar_proto_rawDescGZIP(), []int{3} + return file_calendar_proto_rawDescGZIP(), []int{4} } func (x *UpdateEventRequest) GetId() int64 { @@ -348,7 +427,7 @@ type DeleteEventRequest struct { func (x *DeleteEventRequest) Reset() { *x = DeleteEventRequest{} if protoimpl.UnsafeEnabled { - mi := &file_calendar_proto_msgTypes[4] + mi := &file_calendar_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -361,7 +440,7 @@ func (x *DeleteEventRequest) String() string { func (*DeleteEventRequest) ProtoMessage() {} func (x *DeleteEventRequest) ProtoReflect() protoreflect.Message { - mi := &file_calendar_proto_msgTypes[4] + mi := &file_calendar_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -374,7 +453,7 @@ func (x *DeleteEventRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteEventRequest.ProtoReflect.Descriptor instead. func (*DeleteEventRequest) Descriptor() ([]byte, []int) { - return file_calendar_proto_rawDescGZIP(), []int{4} + return file_calendar_proto_rawDescGZIP(), []int{5} } func (x *DeleteEventRequest) GetId() int64 { @@ -384,6 +463,53 @@ func (x *DeleteEventRequest) GetId() int64 { return 0 } +type GetUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetUserRequest) Reset() { + *x = GetUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_calendar_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserRequest) ProtoMessage() {} + +func (x *GetUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_calendar_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserRequest.ProtoReflect.Descriptor instead. +func (*GetUserRequest) Descriptor() ([]byte, []int) { + return file_calendar_proto_rawDescGZIP(), []int{6} +} + +func (x *GetUserRequest) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + var File_calendar_proto protoreflect.FileDescriptor var file_calendar_proto_rawDesc = []byte{ @@ -393,10 +519,10 @@ var file_calendar_proto_rawDesc = []byte{ 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf9, 0x01, 0x0a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, 0x02, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x14, + 0x28, 0x05, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, @@ -408,8 +534,16 @@ var file_calendar_proto_rawDesc = []byte{ 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x46, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x22, 0x30, 0x0a, 0x0e, 0x45, 0x76, 0x65, 0x6e, + 0x65, 0x64, 0x46, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x66, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, + 0x0a, 0x09, 0x46, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x46, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x4c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x4c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x0e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x49, 0x0a, 0x12, 0x51, 0x75, @@ -423,31 +557,39 @@ var file_calendar_proto_rawDesc = []byte{ 0x76, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x2a, - 0x3b, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, - 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x45, 0x45, 0x4b, 0x10, - 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x03, 0x32, 0xa4, 0x02, 0x0a, - 0x08, 0x43, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x12, 0x4e, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x13, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, - 0x79, 0x70, 0x65, 0x7d, 0x2f, 0x7b, 0x74, 0x73, 0x7d, 0x12, 0x31, 0x0a, 0x0b, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x1a, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, - 0x22, 0x07, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x43, 0x0a, 0x0b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, - 0x1a, 0x0c, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x01, - 0x2a, 0x12, 0x50, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x13, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x14, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x2a, 0x0c, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, + 0x64, 0x2a, 0x3b, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x07, 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x45, 0x45, + 0x4b, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x03, 0x32, 0x8b, + 0x03, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x12, 0x4e, 0x0a, 0x09, 0x47, + 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x13, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, + 0x7b, 0x74, 0x79, 0x70, 0x65, 0x7d, 0x2f, 0x7b, 0x74, 0x73, 0x7d, 0x12, 0x31, 0x0a, 0x0b, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x06, 0x2e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x1a, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x0c, 0x22, 0x07, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x12, 0x43, + 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x06, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x11, 0x1a, 0x0c, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x3a, 0x01, 0x2a, 0x12, 0x50, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x13, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x2a, 0x0c, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x36, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x12, 0x0f, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, + 0x12, 0x0b, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x2d, 0x0a, + 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x05, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x1a, 0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x0b, 0x22, 0x06, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x01, 0x2a, 0x42, 0x0a, 0x5a, 0x08, + 0x2e, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -464,38 +606,44 @@ func file_calendar_proto_rawDescGZIP() []byte { var ( file_calendar_proto_enumTypes = make([]protoimpl.EnumInfo, 1) - file_calendar_proto_msgTypes = make([]protoimpl.MessageInfo, 5) + file_calendar_proto_msgTypes = make([]protoimpl.MessageInfo, 7) file_calendar_proto_goTypes = []interface{}{ (QueryRangeType)(0), // 0: QueryRangeType (*Event)(nil), // 1: Event - (*EventsResponse)(nil), // 2: EventsResponse - (*QueryEventsRequest)(nil), // 3: QueryEventsRequest - (*UpdateEventRequest)(nil), // 4: UpdateEventRequest - (*DeleteEventRequest)(nil), // 5: DeleteEventRequest - (*timestamp.Timestamp)(nil), // 6: google.protobuf.Timestamp - (*empty.Empty)(nil), // 7: google.protobuf.Empty + (*User)(nil), // 2: User + (*EventsResponse)(nil), // 3: EventsResponse + (*QueryEventsRequest)(nil), // 4: QueryEventsRequest + (*UpdateEventRequest)(nil), // 5: UpdateEventRequest + (*DeleteEventRequest)(nil), // 6: DeleteEventRequest + (*GetUserRequest)(nil), // 7: GetUserRequest + (*timestamp.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*empty.Empty)(nil), // 9: google.protobuf.Empty } ) var file_calendar_proto_depIdxs = []int32{ - 6, // 0: Event.StartDate:type_name -> google.protobuf.Timestamp - 6, // 1: Event.EndDate:type_name -> google.protobuf.Timestamp - 1, // 2: EventsResponse.events:type_name -> Event - 0, // 3: QueryEventsRequest.type:type_name -> QueryRangeType - 1, // 4: UpdateEventRequest.event:type_name -> Event - 3, // 5: Calendar.GetEvents:input_type -> QueryEventsRequest - 1, // 6: Calendar.CreateEvent:input_type -> Event - 4, // 7: Calendar.UpdateEvent:input_type -> UpdateEventRequest - 5, // 8: Calendar.DeleteEvent:input_type -> DeleteEventRequest - 2, // 9: Calendar.GetEvents:output_type -> EventsResponse - 1, // 10: Calendar.CreateEvent:output_type -> Event - 1, // 11: Calendar.UpdateEvent:output_type -> Event - 7, // 12: Calendar.DeleteEvent:output_type -> google.protobuf.Empty - 9, // [9:13] is the sub-list for method output_type - 5, // [5:9] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 8, // 0: Event.StartDate:type_name -> google.protobuf.Timestamp + 8, // 1: Event.EndDate:type_name -> google.protobuf.Timestamp + 1, // 2: EventsResponse.events:type_name -> Event + 0, // 3: QueryEventsRequest.type:type_name -> QueryRangeType + 1, // 4: UpdateEventRequest.event:type_name -> Event + 4, // 5: Calendar.GetEvents:input_type -> QueryEventsRequest + 1, // 6: Calendar.CreateEvent:input_type -> Event + 5, // 7: Calendar.UpdateEvent:input_type -> UpdateEventRequest + 6, // 8: Calendar.DeleteEvent:input_type -> DeleteEventRequest + 7, // 9: Calendar.GetUser:input_type -> GetUserRequest + 2, // 10: Calendar.CreateUser:input_type -> User + 3, // 11: Calendar.GetEvents:output_type -> EventsResponse + 1, // 12: Calendar.CreateEvent:output_type -> Event + 1, // 13: Calendar.UpdateEvent:output_type -> Event + 9, // 14: Calendar.DeleteEvent:output_type -> google.protobuf.Empty + 2, // 15: Calendar.GetUser:output_type -> User + 2, // 16: Calendar.CreateUser:output_type -> User + 11, // [11:17] is the sub-list for method output_type + 5, // [5:11] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_calendar_proto_init() } @@ -517,7 +665,7 @@ func file_calendar_proto_init() { } } file_calendar_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EventsResponse); i { + switch v := v.(*User); i { case 0: return &v.state case 1: @@ -529,7 +677,7 @@ func file_calendar_proto_init() { } } file_calendar_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryEventsRequest); i { + switch v := v.(*EventsResponse); i { case 0: return &v.state case 1: @@ -541,7 +689,7 @@ func file_calendar_proto_init() { } } file_calendar_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateEventRequest); i { + switch v := v.(*QueryEventsRequest); i { case 0: return &v.state case 1: @@ -553,6 +701,18 @@ func file_calendar_proto_init() { } } file_calendar_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateEventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_calendar_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteEventRequest); i { case 0: return &v.state @@ -564,6 +724,18 @@ func file_calendar_proto_init() { return nil } } + file_calendar_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -571,7 +743,7 @@ func file_calendar_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_calendar_proto_rawDesc, NumEnums: 1, - NumMessages: 5, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, @@ -604,6 +776,8 @@ type CalendarClient interface { CreateEvent(ctx context.Context, in *Event, opts ...grpc.CallOption) (*Event, error) UpdateEvent(ctx context.Context, in *UpdateEventRequest, opts ...grpc.CallOption) (*Event, error) DeleteEvent(ctx context.Context, in *DeleteEventRequest, opts ...grpc.CallOption) (*empty.Empty, error) + GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) + CreateUser(ctx context.Context, in *User, opts ...grpc.CallOption) (*User, error) } type calendarClient struct { @@ -650,12 +824,32 @@ func (c *calendarClient) DeleteEvent(ctx context.Context, in *DeleteEventRequest return out, nil } +func (c *calendarClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) { + out := new(User) + err := c.cc.Invoke(ctx, "/Calendar/GetUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *calendarClient) CreateUser(ctx context.Context, in *User, opts ...grpc.CallOption) (*User, error) { + out := new(User) + err := c.cc.Invoke(ctx, "/Calendar/CreateUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // CalendarServer is the server API for Calendar service. type CalendarServer interface { GetEvents(context.Context, *QueryEventsRequest) (*EventsResponse, error) CreateEvent(context.Context, *Event) (*Event, error) UpdateEvent(context.Context, *UpdateEventRequest) (*Event, error) DeleteEvent(context.Context, *DeleteEventRequest) (*empty.Empty, error) + GetUser(context.Context, *GetUserRequest) (*User, error) + CreateUser(context.Context, *User) (*User, error) } // UnimplementedCalendarServer can be embedded to have forward compatible implementations. @@ -678,6 +872,14 @@ func (*UnimplementedCalendarServer) DeleteEvent(context.Context, *DeleteEventReq return nil, status.Errorf(codes.Unimplemented, "method DeleteEvent not implemented") } +func (*UnimplementedCalendarServer) GetUser(context.Context, *GetUserRequest) (*User, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") +} + +func (*UnimplementedCalendarServer) CreateUser(context.Context, *User) (*User, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented") +} + func RegisterCalendarServer(s *grpc.Server, srv CalendarServer) { s.RegisterService(&_Calendar_serviceDesc, srv) } @@ -754,6 +956,42 @@ func _Calendar_DeleteEvent_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Calendar_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CalendarServer).GetUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Calendar/GetUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CalendarServer).GetUser(ctx, req.(*GetUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Calendar_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(User) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CalendarServer).CreateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Calendar/CreateUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CalendarServer).CreateUser(ctx, req.(*User)) + } + return interceptor(ctx, in, info, handler) +} + var _Calendar_serviceDesc = grpc.ServiceDesc{ ServiceName: "Calendar", HandlerType: (*CalendarServer)(nil), @@ -774,6 +1012,14 @@ var _Calendar_serviceDesc = grpc.ServiceDesc{ MethodName: "DeleteEvent", Handler: _Calendar_DeleteEvent_Handler, }, + { + MethodName: "GetUser", + Handler: _Calendar_GetUser_Handler, + }, + { + MethodName: "CreateUser", + Handler: _Calendar_CreateUser_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "calendar.proto", diff --git a/hw12_13_14_15_calendar/service/server/calendar.pb.gw.go b/hw12_13_14_15_calendar/service/server/calendar.pb.gw.go index 6f83a40..a27b072 100644 --- a/hw12_13_14_15_calendar/service/server/calendar.pb.gw.go +++ b/hw12_13_14_15_calendar/service/server/calendar.pb.gw.go @@ -265,6 +265,90 @@ func local_request_Calendar_DeleteEvent_0(ctx context.Context, marshaler runtime return msg, metadata, err } +func request_Calendar_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, client CalendarClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.GetUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Calendar_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, server CalendarServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.GetUser(ctx, &protoReq) + return msg, metadata, err +} + +func request_Calendar_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, client CalendarClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq User + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Calendar_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, server CalendarServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq User + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateUser(ctx, &protoReq) + return msg, metadata, err +} + // RegisterCalendarHandlerServer registers the http handlers for service Calendar to "mux". // UnaryRPC :call CalendarServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -346,6 +430,44 @@ func RegisterCalendarHandlerServer(ctx context.Context, mux *runtime.ServeMux, s forward_Calendar_DeleteEvent_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("GET", pattern_Calendar_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Calendar_GetUser_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Calendar_GetUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Calendar_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Calendar_CreateUser_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Calendar_CreateUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -462,6 +584,44 @@ func RegisterCalendarHandlerClient(ctx context.Context, mux *runtime.ServeMux, c forward_Calendar_DeleteEvent_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("GET", pattern_Calendar_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Calendar_GetUser_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Calendar_GetUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + + mux.Handle("POST", pattern_Calendar_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Calendar_CreateUser_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Calendar_CreateUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -473,6 +633,10 @@ var ( pattern_Calendar_UpdateEvent_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"events", "id"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Calendar_DeleteEvent_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"events", "id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Calendar_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"users", "id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Calendar_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"users"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -483,4 +647,8 @@ var ( forward_Calendar_UpdateEvent_0 = runtime.ForwardResponseMessage forward_Calendar_DeleteEvent_0 = runtime.ForwardResponseMessage + + forward_Calendar_GetUser_0 = runtime.ForwardResponseMessage + + forward_Calendar_CreateUser_0 = runtime.ForwardResponseMessage ) diff --git a/hw12_13_14_15_calendar/service/server/handlers.go b/hw12_13_14_15_calendar/service/server/handlers.go index 5e7ba57..32a8fc3 100644 --- a/hw12_13_14_15_calendar/service/server/handlers.go +++ b/hw12_13_14_15_calendar/service/server/handlers.go @@ -72,6 +72,7 @@ func (s *Service) GetEvents(ctx context.Context, query *QueryEventsRequest) (res } result.Events = append(result.Events, converted) } + fmt.Printf("result.Events %+v\n", result.Events) return } @@ -93,9 +94,10 @@ func (s *Service) CreateEvent(ctx context.Context, event *Event) (result *Event, } func (s *Service) UpdateEvent(ctx context.Context, data *UpdateEventRequest) (result *Event, err error) { + log.Debug().Msgf("[GRPC] Update Event, incoming data: %+v\n", data) obj, err := ConvertEventFromProto(data.Event) if err != nil { - err = status.Errorf(codes.InvalidArgument, "%s", err) + err = status.Errorf(codes.InvalidArgument, "converting event from proto error %s", err) return } evt, err := s.r.UpdateEvent(data.Id, *obj) @@ -112,3 +114,31 @@ func (s *Service) UpdateEvent(ctx context.Context, data *UpdateEventRequest) (re func (s *Service) DeleteEvent(ctx context.Context, data *DeleteEventRequest) (*empty.Empty, error) { return &empty.Empty{}, s.r.DeleteEvent(data.Id) } + +func (s *Service) CreateUser(ctx context.Context, user *User) (result *User, err error) { + log.Debug().Msgf("[GRPC] Receiving User obj: %+v\n", user) + obj, err := ConvertUserFromProto(user) + if err != nil { + err = status.Errorf(codes.InvalidArgument, "%s", err) + return + } + usr, err := s.r.CreateUser(*obj) + if err != nil { + if _, ok := err.(validator.ValidationErrors); ok { + err = status.Errorf(codes.InvalidArgument, "%s", err) + fmt.Println("ERRRR", err) + } + return + } + log.Debug().Msgf("[GRPC] Created User: %+v\n", usr) + return ConvertUserToProto(usr) +} + +func (s *Service) GetUser(ctx context.Context, query *GetUserRequest) (result *User, err error) { + obj, err := s.r.GetUser(query.GetId()) + if err != nil { + err = status.Errorf(codes.NotFound, "%s", err) + return + } + return ConvertUserToProto(obj) +} diff --git a/hw12_13_14_15_calendar/service/server/utils.go b/hw12_13_14_15_calendar/service/server/utils.go index 0601233..7356c3b 100644 --- a/hw12_13_14_15_calendar/service/server/utils.go +++ b/hw12_13_14_15_calendar/service/server/utils.go @@ -35,10 +35,11 @@ func ConvertTimeToTimestamp(ntime sql.NullTime) (result *timestamp.Timestamp, er // Didn't want to use reflection. func ConvertEventToProto(evt repository.Event) (*Event, error) { result := &Event{ - ID: evt.ID, - UserID: evt.UserID, + ID: int32(evt.ID), + UserID: int32(evt.UserID), Title: evt.Title, - NotifiedFor: int64(evt.NotifiedFor), + Status: evt.Status, + NotifiedFor: int32(evt.NotifiedFor), } value, err := ptypes.TimestampProto(evt.StartDate) if err != nil { @@ -62,17 +63,20 @@ func ConvertEventFromProto(evt *Event) (*repository.Event, error) { } result := repository.Event{} if evt.ID != 0 { - result.ID = evt.ID + result.ID = int64(evt.ID) } if evt.UserID != 0 { - result.UserID = evt.UserID + result.UserID = int64(evt.UserID) } if evt.NotifiedFor != 0 { - result.NotifiedFor = int(evt.NotifiedFor) + result.NotifiedFor = int64(evt.NotifiedFor) } if evt.Title != "" { result.Title = evt.Title } + if evt.Status != "" { + result.Status = evt.Status + } if evt.StartDate != nil { result.StartDate = time.Unix(evt.StartDate.GetSeconds(), int64(evt.StartDate.GetNanos())) } @@ -81,3 +85,45 @@ func ConvertEventFromProto(evt *Event) (*repository.Event, error) { } return &result, nil } + +func ConvertUserToProto(data repository.User) (*User, error) { + result := &User{ + ID: int32(data.ID), + Email: data.Email, + } + tmp, _ := data.FirstName.Value() + if v, ok := tmp.(string); ok { + result.FirstName = v + } + tmp, _ = data.LastName.Value() + if v, ok := tmp.(string); ok { + result.LastName = v + } + return result, nil +} + +func ConvertUserFromProto(usr *User) (*repository.User, error) { + if usr == nil { + return nil, ErrObjectIsNil + } + result := repository.User{} + if usr.ID != 0 { + result.ID = int64(usr.ID) + } + if usr.Email != "" { + result.Email = usr.Email + } + if usr.FirstName != "" { + result.FirstName = sql.NullString{ + String: usr.FirstName, + Valid: true, + } + } + if usr.LastName != "" { + result.LastName = sql.NullString{ + String: usr.LastName, + Valid: true, + } + } + return &result, nil +} diff --git a/hw12_13_14_15_calendar/service/service_test.go b/hw12_13_14_15_calendar/service/service_test.go index 1309ec3..fc30386 100644 --- a/hw12_13_14_15_calendar/service/service_test.go +++ b/hw12_13_14_15_calendar/service/service_test.go @@ -7,7 +7,6 @@ import ( "log" "net/http" "os" - "strconv" "strings" "testing" "time" @@ -26,8 +25,8 @@ type DataEvent struct { } type JSONEvent struct { - ID string `json:"ID"` - UserID string `json:"UserID"` + ID int64 `json:"ID"` + UserID int64 `json:"UserID"` Title string `json:"Title"` StartDate string `json:"StartDate"` EndDate string `json:"EndDate"` @@ -59,10 +58,10 @@ func createEvent(ID int64, startDate time.Time, endDate time.Time) repository.Ev func getEventsFromStorage(ids []int64) (result []JSONEvent) { for _, id := range ids { - evt := (*repo.GetStorage())[id] + evt := (*repo.GetStorageEvents())[id] result = append(result, JSONEvent{ - ID: strconv.Itoa(int(evt.ID)), - UserID: strconv.Itoa(int(evt.UserID)), + ID: int64(evt.ID), + UserID: int64(evt.UserID), Title: evt.Title, StartDate: evt.StartDate.Format(time.RFC3339), EndDate: evt.EndDate.Format(time.RFC3339), @@ -107,7 +106,7 @@ func resetStorage() { } func fillRepo(event repository.Event) { - (*repo.GetStorage())[event.ID] = event + (*repo.GetStorageEvents())[event.ID] = event } func teardown() { @@ -180,13 +179,13 @@ func TestDeleteEvent(t *testing.T) { var eventId int64 = 5 resetStorage() - _, ok := (*repo.GetStorage())[eventId] + _, ok := (*repo.GetStorageEvents())[eventId] require.True(t, ok) body := makeQuery(t, http.MethodDelete, fmt.Sprintf("%s/%d", getUrl(), eventId), "{}") require.Equal(t, string(body), "{}") - _, ok = (*repo.GetStorage())[eventId] + _, ok = (*repo.GetStorageEvents())[eventId] require.False(t, ok) } @@ -208,10 +207,9 @@ func TestCreateEvent(t *testing.T) { var created JSONEvent err = json.Unmarshal(body, &created) - intId, err := strconv.Atoi(created.ID) require.Nil(t, err) - _, ok := (*repo.GetStorage())[int64(intId)] + _, ok := (*repo.GetStorageEvents())[created.ID] require.True(t, ok) } @@ -225,7 +223,7 @@ func TestUpdateEvent(t *testing.T) { Event DataObject `json:"event"` }{DataObject{"Updated Title"}} - require.NotEqual(t, (*repo.GetStorage())[eventID].Title, "Updated Title") + require.NotEqual(t, (*repo.GetStorageEvents())[eventID].Title, "Updated Title") converted, err := json.Marshal(event) require.Nil(t, err) @@ -237,5 +235,5 @@ func TestUpdateEvent(t *testing.T) { require.Nil(t, err) require.Equal(t, updated.Title, "Updated Title") - require.Equal(t, (*repo.GetStorage())[eventID].Title, "Updated Title") + require.Equal(t, (*repo.GetStorageEvents())[eventID].Title, "Updated Title") } diff --git a/hw12_13_14_15_calendar/tools.go b/hw12_13_14_15_calendar/tools.go index 2789bf0..80363ba 100644 --- a/hw12_13_14_15_calendar/tools.go +++ b/hw12_13_14_15_calendar/tools.go @@ -5,5 +5,6 @@ package hwcalendar import ( _ "github.com/golang/protobuf/protoc-gen-go" _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway" + _ "github.com/onsi/ginkgo/ginkgo" _ "github.com/pressly/goose" )