diff --git a/src/backend/docker/docker-compose.yml b/src/backend/docker/docker-compose.yml index aefef861b..2ae526a22 100644 --- a/src/backend/docker/docker-compose.yml +++ b/src/backend/docker/docker-compose.yml @@ -36,7 +36,7 @@ services: - redis restart: always ports: - - 5200 + - 5200:5200 order-api: image: restaurant/order-api diff --git a/src/backend/services/cart-api/cmd/api/main.go b/src/backend/services/cart-api/cmd/api/main.go index 4b6062a42..48b7b4547 100644 --- a/src/backend/services/cart-api/cmd/api/main.go +++ b/src/backend/services/cart-api/cmd/api/main.go @@ -14,21 +14,21 @@ import ( "github.com/dnwe/otelsarama" "github.com/jurabek/cart-api/cmd/config" "github.com/jurabek/cart-api/internal/database" - "github.com/jurabek/cart-api/internal/docs" "github.com/jurabek/cart-api/internal/events" grpcsvc "github.com/jurabek/cart-api/internal/grpc" "github.com/jurabek/cart-api/internal/handlers" - "github.com/jurabek/cart-api/internal/middlewares" + "github.com/jurabek/cart-api/internal/instrumentation" pbv1 "github.com/jurabek/cart-api/pb/v1" "github.com/jurabek/cart-api/pkg/reciever" "github.com/redis/go-redis/v9" + "github.com/swaggo/swag/example/basic/docs" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/reflection" "github.com/redis/go-redis/extra/redisotel/v9" - "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" @@ -41,12 +41,6 @@ import ( "github.com/jurabek/cart-api/internal/repositories" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - - "github.com/gin-gonic/gin" - - // swagger embed files // docs is generated by Swag CLI, you have to import it. - swaggerFiles "github.com/swaggo/files" // swagger embed files - ginSwagger "github.com/swaggo/gin-swagger" // gin-swagger middleware ) var ( @@ -68,35 +62,18 @@ var ( func main() { ctx := context.Background() zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - gin.SetMode(gin.DebugMode) basePath, _ := os.LookupEnv("BASE_PATH") docs.SwaggerInfo.BasePath = basePath - tp, err := initTracer(ctx) + close, err := instrumentation.StartOTEL(ctx) if err != nil { - log.Fatal().Err(err) - } - - mr, err := initMeter(ctx) - if err != nil { - log.Fatal().Err(err) + log.Fatal().Err(err).Msg("Error starting otel") } - - defer func() { - if err := tp.Shutdown(context.Background()); err != nil { - log.Printf("Error shutting down tracer provider: %v", err) - } - if err := mr.Shutdown(context.Background()); err != nil { - log.Printf("Error shutting down meter provider: %v", err) - } - }() + defer close() handleSigterm() - router := gin.Default() - router.Use(middlewares.RequestMiddleware()) - router.Use(otelgin.Middleware("cart-api")) - + router := http.NewServeMux() cfg := config.Init() redisClient, err := initRedis(cfg.RedisHost) @@ -124,30 +101,22 @@ func main() { go grpcServer(grpcsvc.NewCartGrpcService(cartRepository)) cartHandler := handlers.NewCartHandler(cartRepository) - apiV1 := router.Group(basePath + "/api/v1") - { - cart := apiV1.Group("/cart") - { - cart.POST("", handlers.ErrorHandler(cartHandler.Create)) - cart.GET(":id", handlers.ErrorHandler(cartHandler.Get)) - cart.DELETE(":id", handlers.ErrorHandler(cartHandler.Delete)) - cart.PUT(":id", handlers.ErrorHandler(cartHandler.Update)) - cart.POST(":id/item", handlers.ErrorHandler(cartHandler.AddItem)) // adds item or increments quantity by CartID - cart.PUT(":id/item/:itemID", handlers.ErrorHandler(cartHandler.UpdateItem)) // updates line item item_id is ignored - cart.DELETE(":id/item/:itemID", handlers.ErrorHandler(cartHandler.DeleteItem)) - } - } - // Home page should be redirected to swagger page - router.GET(basePath+"/", func(c *gin.Context) { - c.Redirect(http.StatusMovedPermanently, basePath+"/swagger/index.html") - }) + cartBasePath := basePath + "/api/v1/cart" + router.HandleFunc("POST "+cartBasePath, handlers.ErrorHandler(cartHandler.Create)) + router.HandleFunc("GET "+cartBasePath+":id", handlers.ErrorHandler(cartHandler.Get)) + router.HandleFunc("DELETE "+cartBasePath+":id", handlers.ErrorHandler(cartHandler.Delete)) + router.HandleFunc("PUT "+cartBasePath+":id", handlers.ErrorHandler(cartHandler.Update)) + router.HandleFunc("POST "+cartBasePath+":id/item", handlers.ErrorHandler(cartHandler.AddItem)) // adds item or increments quantity by CartID + router.HandleFunc("PUT "+cartBasePath+":id/item/:itemID", handlers.ErrorHandler(cartHandler.UpdateItem)) // updates line item item_id is ignored + router.HandleFunc("DELETE "+cartBasePath+":id/item/:itemID", handlers.ErrorHandler(cartHandler.DeleteItem)) + + otelRouter := otelhttp.NewHandler(router, "server", + otelhttp.WithMessageEvents(otelhttp.ReadEvents, otelhttp.WriteEvents), + ) - router.GET(basePath+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, - func(c *ginSwagger.Config) { - c.URL = basePath + "/swagger/doc.json" - })) - _ = router.Run() + log.Info().Msg("Starting server on port 8080...") + log.Fatal().Err(http.ListenAndServe(":5200", otelRouter)) } func grpcServer(svc pbv1.CartServiceServer) { @@ -243,7 +212,7 @@ func initMeter(ctx context.Context) (*sdkmetric.MeterProvider, error) { return nil, err } - mp := sdkmetric.NewMeterProvider( + mp := sdkmetric.NewMeterProvider( sdkmetric.WithResource(res), sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exp)), ) diff --git a/src/backend/services/cart-api/go.mod b/src/backend/services/cart-api/go.mod index fa2ecbf8c..d0b2217bf 100644 --- a/src/backend/services/cart-api/go.mod +++ b/src/backend/services/cart-api/go.mod @@ -3,15 +3,12 @@ module github.com/jurabek/cart-api go 1.22 require ( - github.com/gin-gonic/gin v1.9.1 github.com/gomodule/redigo v2.0.0+incompatible - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/redis/go-redis/v9 v9.0.5 github.com/rs/zerolog v1.31.0 github.com/stretchr/testify v1.8.4 - github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.2 - go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.47.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 go.opentelemetry.io/otel v1.24.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 @@ -22,24 +19,25 @@ require ( github.com/IBM/sarama v1.42.1 github.com/dnwe/otelsarama v0.0.0-20231212173111-631a0a53d5d4 github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0 + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.24.0 + go.opentelemetry.io/otel/sdk/metric v1.24.0 ) require ( - github.com/bytedance/sonic v1.10.2 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect - github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/eapache/go-resiliency v1.4.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect @@ -50,53 +48,36 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect - golang.org/x/arch v0.7.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect + go.opentelemetry.io/proto/otlp v1.1.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect ) require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.14 // indirect github.com/go-openapi/swag v0.22.7 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.17.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/leodido/go-urn v1.2.4 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/swaggo/files v1.0.1 - github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.17.0 // indirect - google.golang.org/grpc v1.60.1 + google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/src/backend/services/cart-api/go.sum b/src/backend/services/cart-api/go.sum index 15baa04a7..5a4df52f5 100644 --- a/src/backend/services/cart-api/go.sum +++ b/src/backend/services/cart-api/go.sum @@ -1,5 +1,5 @@ -cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/IBM/sarama v1.42.1 h1:wugyWa15TDEHh2kvq2gAy1IHLjEjuYOYgXz/ruC/OSQ= @@ -10,23 +10,12 @@ github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= -github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= -github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= -github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -43,16 +32,10 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= -github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -66,19 +49,7 @@ github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/ github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= -github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -89,13 +60,12 @@ github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -118,20 +88,12 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -140,13 +102,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -170,63 +125,41 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= -github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= -github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= -github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.47.0 h1:klI20G/ha94DQjyGuZ8Ajzi3B0C/kVFOESf58tMRq/8= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.47.0/go.mod h1:uVxaSGXSHkn60f5XyeNe4UVg+4eXVxmi0fg1ja42uCQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= -go.opentelemetry.io/contrib/propagators/b3 v1.22.0 h1:Okbgv0pWHMQq+mF7H2o1mucJ5PvxKFq2c8cyqoXfeaQ= -go.opentelemetry.io/contrib/propagators/b3 v1.22.0/go.mod h1:N3z0ycFRhsVZ+tG/uavMxHvOvFE95QM6gwW1zSqT9dQ= -go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= -go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0 h1:f2jriWfOdldanBwS9jNBdeOKAQN7b4ugAMaNu1/1k9g= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.24.0/go.mod h1:B+bcQI1yTY+N0vqMpoZbEN7+XU4tNM0DmUiOwebFJWI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYaZCdNu1V73tm4TvXs2ntl98C4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 h1:H2JFgRcGiyHg7H7bwcwaQJYrNFqCqrbTQ8K4p1OvDu8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0/go.mod h1:WfCWp1bGoYK8MeULtI15MmQVczfR+bFkk0DF3h06QmQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.24.0 h1:JYE2HM7pZbOt5Jhk8ndWZTUWYOVift2cHjXVMkPdmdc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.24.0/go.mod h1:yMb/8c6hVsnma0RpsBMNo0fEiQKeclawtgaIaOp2MLY= -go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= -go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= -go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/sdk/metric v1.24.0 h1:yyMQrPzF+k88/DbH7o4FMAs80puqd+9osbiBrJrz/w8= go.opentelemetry.io/otel/sdk/metric v1.24.0/go.mod h1:I6Y5FjH6rvEnTTAYQz3Mmv2kl6Ek5IIrmwTLqMrrOE0= -go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= -go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= +go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= @@ -243,8 +176,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= @@ -258,8 +191,6 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -280,14 +211,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos= +google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= @@ -299,5 +230,3 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/src/backend/services/cart-api/internal/docs/docs.go b/src/backend/services/cart-api/internal/docs/docs.go deleted file mode 100644 index 4e8d12d13..000000000 --- a/src/backend/services/cart-api/internal/docs/docs.go +++ /dev/null @@ -1,518 +0,0 @@ -// Package docs Code generated by swaggo/swag. DO NOT EDIT -package docs - -import "github.com/swaggo/swag" - -const docTemplate = `{ - "schemes": {{ marshal .Schemes }}, - "swagger": "2.0", - "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "API Support", - "url": "http://www.swagger.io/support", - "email": "support@swagger.io" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - "version": "{{.Version}}" - }, - "host": "{{.Host}}", - "basePath": "{{.BasePath}}", - "paths": { - "/cart": { - "post": { - "description": "add by json new Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Creates new cart", - "parameters": [ - { - "description": "Creates new cart", - "name": "cart", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.CreateCartReq" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - }, - "/cart/{id}": { - "get": { - "description": "Get Cart by ID", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Gets a Cart", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - }, - "put": { - "description": "update by json cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Update cart", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Updates cart", - "name": "update_cart", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.CreateCartReq" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - }, - "delete": { - "description": "Deletes Cart by ID", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Deletes a Cart", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - }, - "/cart/{id}/item": { - "post": { - "description": "Adds item into cart, if item exists sums the quantity", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Add a line item", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Update line item", - "name": "lineItem", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.LineItem" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - }, - "/cart/{id}/item/{itemID}": { - "put": { - "description": "Updates item in the cart,", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Updates a line item", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Item ID", - "name": "itemID", - "in": "path", - "required": true - }, - { - "description": "Update line item", - "name": "lineItem", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.LineItem" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - }, - "delete": { - "description": "Delete line item by json", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Delete line item", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Item ID", - "name": "itemID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - } - }, - "definitions": { - "models.Cart": { - "type": "object", - "properties": { - "currency": { - "type": "string" - }, - "discount": { - "type": "number" - }, - "id": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/models.LineItem" - } - }, - "shipping": { - "type": "number" - }, - "shipping_method": { - "type": "string" - }, - "status": { - "type": "string" - }, - "tax": { - "type": "number" - }, - "total": { - "type": "number" - }, - "user_id": { - "type": "string" - } - } - }, - "models.CreateCartReq": { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/models.LineItem" - } - }, - "user_id": { - "type": "string" - } - } - }, - "models.HTTPError": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "example": 400 - }, - "message": { - "type": "string", - "example": "status bad request" - } - } - }, - "models.LineItem": { - "type": "object", - "properties": { - "attributes": { - "type": "object", - "additionalProperties": true - }, - "img": { - "type": "string" - }, - "item_id": { - "type": "integer" - }, - "product_description": { - "type": "string" - }, - "product_name": { - "type": "string" - }, - "quantity": { - "type": "integer" - }, - "unit_price": { - "type": "number" - } - } - } - } -}` - -// SwaggerInfo holds exported Swagger Info so clients can modify it -var SwaggerInfo = &swag.Spec{ - Version: "1.0", - Host: "", - BasePath: "", - Schemes: []string{}, - Title: "Cart API", - Description: "This is a rest api for cart which saves items to redis server", - InfoInstanceName: "swagger", - SwaggerTemplate: docTemplate, - LeftDelim: "{{", - RightDelim: "}}", -} - -func init() { - swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) -} diff --git a/src/backend/services/cart-api/internal/docs/fix.go b/src/backend/services/cart-api/internal/docs/fix.go deleted file mode 100644 index edc7e209f..000000000 --- a/src/backend/services/cart-api/internal/docs/fix.go +++ /dev/null @@ -1,8 +0,0 @@ -package docs - -import "strings" - -// OverrideAuthURL Initializes docs for custom Auth Url -func OverrideAuthURL(authURL string) string { - return strings.ReplaceAll(docTemplate, "{{.AuthUrl}}", authURL) -} diff --git a/src/backend/services/cart-api/internal/docs/swagger.json b/src/backend/services/cart-api/internal/docs/swagger.json deleted file mode 100644 index 1aa3d6ae6..000000000 --- a/src/backend/services/cart-api/internal/docs/swagger.json +++ /dev/null @@ -1,492 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "description": "This is a rest api for cart which saves items to redis server", - "title": "Cart API", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "API Support", - "url": "http://www.swagger.io/support", - "email": "support@swagger.io" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - "version": "1.0" - }, - "paths": { - "/cart": { - "post": { - "description": "add by json new Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Creates new cart", - "parameters": [ - { - "description": "Creates new cart", - "name": "cart", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.CreateCartReq" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - }, - "/cart/{id}": { - "get": { - "description": "Get Cart by ID", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Gets a Cart", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - }, - "put": { - "description": "update by json cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Update cart", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Updates cart", - "name": "update_cart", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.CreateCartReq" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - }, - "delete": { - "description": "Deletes Cart by ID", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Deletes a Cart", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - }, - "/cart/{id}/item": { - "post": { - "description": "Adds item into cart, if item exists sums the quantity", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Add a line item", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Update line item", - "name": "lineItem", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.LineItem" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - }, - "/cart/{id}/item/{itemID}": { - "put": { - "description": "Updates item in the cart,", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Updates a line item", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Item ID", - "name": "itemID", - "in": "path", - "required": true - }, - { - "description": "Update line item", - "name": "lineItem", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/models.LineItem" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - }, - "delete": { - "description": "Delete line item by json", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "summary": "Delete line item", - "parameters": [ - { - "type": "string", - "description": "Cart ID", - "name": "id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Item ID", - "name": "itemID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.Cart" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/models.HTTPError" - } - } - } - } - } - }, - "definitions": { - "models.Cart": { - "type": "object", - "properties": { - "currency": { - "type": "string" - }, - "discount": { - "type": "number" - }, - "id": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/models.LineItem" - } - }, - "shipping": { - "type": "number" - }, - "shipping_method": { - "type": "string" - }, - "status": { - "type": "string" - }, - "tax": { - "type": "number" - }, - "total": { - "type": "number" - }, - "user_id": { - "type": "string" - } - } - }, - "models.CreateCartReq": { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/models.LineItem" - } - }, - "user_id": { - "type": "string" - } - } - }, - "models.HTTPError": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "example": 400 - }, - "message": { - "type": "string", - "example": "status bad request" - } - } - }, - "models.LineItem": { - "type": "object", - "properties": { - "attributes": { - "type": "object", - "additionalProperties": true - }, - "img": { - "type": "string" - }, - "item_id": { - "type": "integer" - }, - "product_description": { - "type": "string" - }, - "product_name": { - "type": "string" - }, - "quantity": { - "type": "integer" - }, - "unit_price": { - "type": "number" - } - } - } - } -} \ No newline at end of file diff --git a/src/backend/services/cart-api/internal/docs/swagger.yaml b/src/backend/services/cart-api/internal/docs/swagger.yaml deleted file mode 100644 index 63b23536d..000000000 --- a/src/backend/services/cart-api/internal/docs/swagger.yaml +++ /dev/null @@ -1,327 +0,0 @@ -definitions: - models.Cart: - properties: - currency: - type: string - discount: - type: number - id: - type: string - items: - items: - $ref: '#/definitions/models.LineItem' - type: array - shipping: - type: number - shipping_method: - type: string - status: - type: string - tax: - type: number - total: - type: number - user_id: - type: string - type: object - models.CreateCartReq: - properties: - items: - items: - $ref: '#/definitions/models.LineItem' - type: array - user_id: - type: string - type: object - models.HTTPError: - properties: - code: - example: 400 - type: integer - message: - example: status bad request - type: string - type: object - models.LineItem: - properties: - attributes: - additionalProperties: true - type: object - img: - type: string - item_id: - type: integer - product_description: - type: string - product_name: - type: string - quantity: - type: integer - unit_price: - type: number - type: object -info: - contact: - email: support@swagger.io - name: API Support - url: http://www.swagger.io/support - description: This is a rest api for cart which saves items to redis server - license: - name: Apache 2.0 - url: http://www.apache.org/licenses/LICENSE-2.0.html - termsOfService: http://swagger.io/terms/ - title: Cart API - version: "1.0" -paths: - /cart: - post: - consumes: - - application/json - description: add by json new Cart - parameters: - - description: Creates new cart - in: body - name: cart - required: true - schema: - $ref: '#/definitions/models.CreateCartReq' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Cart' - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/models.HTTPError' - summary: Creates new cart - tags: - - Cart - /cart/{id}: - delete: - consumes: - - application/json - description: Deletes Cart by ID - parameters: - - description: Cart ID - in: path - name: id - required: true - type: string - produces: - - application/json - responses: - "200": - description: "" - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/models.HTTPError' - summary: Deletes a Cart - tags: - - Cart - get: - consumes: - - application/json - description: Get Cart by ID - parameters: - - description: Cart ID - in: path - name: id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Cart' - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - summary: Gets a Cart - tags: - - Cart - put: - consumes: - - application/json - description: update by json cart - parameters: - - description: Cart ID - in: path - name: id - required: true - type: string - - description: Updates cart - in: body - name: update_cart - required: true - schema: - $ref: '#/definitions/models.CreateCartReq' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Cart' - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/models.HTTPError' - summary: Update cart - tags: - - Cart - /cart/{id}/item: - post: - consumes: - - application/json - description: Adds item into cart, if item exists sums the quantity - parameters: - - description: Cart ID - in: path - name: id - required: true - type: string - - description: Update line item - in: body - name: lineItem - required: true - schema: - $ref: '#/definitions/models.LineItem' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Cart' - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/models.HTTPError' - summary: Add a line item - tags: - - Cart - /cart/{id}/item/{itemID}: - delete: - consumes: - - application/json - description: Delete line item by json - parameters: - - description: Cart ID - in: path - name: id - required: true - type: string - - description: Item ID - in: path - name: itemID - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Cart' - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/models.HTTPError' - summary: Delete line item - tags: - - Cart - put: - consumes: - - application/json - description: Updates item in the cart, - parameters: - - description: Cart ID - in: path - name: id - required: true - type: string - - description: Item ID - in: path - name: itemID - required: true - type: string - - description: Update line item - in: body - name: lineItem - required: true - schema: - $ref: '#/definitions/models.LineItem' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.Cart' - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.HTTPError' - "404": - description: Not Found - schema: - $ref: '#/definitions/models.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/models.HTTPError' - summary: Updates a line item - tags: - - Cart -swagger: "2.0" diff --git a/src/backend/services/cart-api/internal/handlers/cart_handler.go b/src/backend/services/cart-api/internal/handlers/cart_handler.go index 6d798d05f..2ca9db684 100644 --- a/src/backend/services/cart-api/internal/handlers/cart_handler.go +++ b/src/backend/services/cart-api/internal/handlers/cart_handler.go @@ -2,13 +2,14 @@ package handlers import ( "context" + "encoding/json" "net/http" "strconv" - "github.com/gin-gonic/gin" "github.com/jurabek/cart-api/internal/models" "github.com/jurabek/cart-api/internal/repositories" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) type GetCreateDeleter interface { @@ -30,17 +31,18 @@ func NewCartHandler(r GetCreateDeleter) *CartHandler { return &CartHandler{repository: r} } -func ErrorHandler(f func(c *gin.Context) error) gin.HandlerFunc { - return func(c *gin.Context) { - err := f(c) +type HandlerFunc func(http.ResponseWriter,*http.Request) + +func ErrorHandler(f func(w http.ResponseWriter, r *http.Request) error) HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + err := f(w, r) if err != nil { var httpErr *models.HTTPError if errors.As(err, &httpErr) { - c.JSON(httpErr.Code, httpErr) - c.Abort() + http.Error(w, httpErr.Error(), httpErr.Code) } } - c.Next() + w.WriteHeader(http.StatusOK) } } @@ -57,24 +59,27 @@ func ErrorHandler(f func(c *gin.Context) error) gin.HandlerFunc { // @Failure 404 {object} models.HTTPError // @Failure 500 {object} models.HTTPError // @Router /cart [post] -func (h *CartHandler) Create(c *gin.Context) error { +func (h *CartHandler) Create(w http.ResponseWriter, r *http.Request) error { + log.Info().Str("path", r.URL.Path).Msg("Create cart") var req models.CreateCartReq - if err := c.BindJSON(&req); err != nil { + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { return models.NewHTTPError(http.StatusBadRequest, err) - } - + } cart := models.MapCreateCartReqToCart(req) - err := h.repository.Update(c.Request.Context(), cart) + err := h.repository.Update(r.Context(), cart) if err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - result, err := h.repository.Get(c.Request.Context(), cart.ID.String()) + result, err := h.repository.Get(r.Context(), cart.ID.String()) if err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - c.JSON(http.StatusOK, result) + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(result); err != nil { + return models.NewHTTPError(http.StatusInternalServerError, err) + } return nil } @@ -92,14 +97,15 @@ func (h *CartHandler) Create(c *gin.Context) error { // @Failure 404 {object} models.HTTPError // @Failure 500 {object} models.HTTPError // @Router /cart/{id} [put] -func (h *CartHandler) Update(c *gin.Context) error { - cartID := c.Param("id") +func (h *CartHandler) Update(w http.ResponseWriter, r *http.Request) error { + cartID := r.PathValue("id") var updateReq models.UpdateCartReq - if err := c.BindJSON(&updateReq); err != nil { + + if err := json.NewDecoder(r.Body).Decode(&updateReq); err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - cart, err := h.repository.Get(c.Request.Context(), cartID) + cart, err := h.repository.Get(r.Context(), cartID) if err != nil { if errors.Is(err, repositories.ErrCartNotFound) { return models.NewHTTPError(http.StatusNotFound, errors.Wrap(err, "cartID: "+cartID)) @@ -108,7 +114,7 @@ func (h *CartHandler) Update(c *gin.Context) error { } cartForUpdate := models.MapUpdateCartReqToCart(cart, updateReq) - if err := h.repository.Update(c.Request.Context(), cartForUpdate); err != nil { + if err := h.repository.Update(r.Context(), cartForUpdate); err != nil { return models.NewHTTPError(http.StatusInternalServerError, err) } return nil @@ -126,17 +132,20 @@ func (h *CartHandler) Update(c *gin.Context) error { // @Failure 400 {object} models.HTTPError // @Failure 404 {object} models.HTTPError // @Router /cart/{id} [get] -func (h *CartHandler) Get(c *gin.Context) error { - id := c.Param("id") - - result, err := h.repository.Get(c.Request.Context(), id) +func (h *CartHandler) Get(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") + result, err := h.repository.Get(r.Context(), id) if err != nil { if errors.Is(err, repositories.ErrCartNotFound) { return models.NewHTTPError(http.StatusNotFound, errors.Wrap(err, "cartID: "+id)) } return models.NewHTTPError(http.StatusInternalServerError, err) } - c.JSON(http.StatusOK, result) + + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(result); err != nil { + return models.NewHTTPError(http.StatusInternalServerError, err) + } return nil } @@ -153,14 +162,13 @@ func (h *CartHandler) Get(c *gin.Context) error { // @Failure 404 {object} models.HTTPError // @Failure 500 {object} models.HTTPError // @Router /cart/{id} [delete] -func (h *CartHandler) Delete(c *gin.Context) error { - id := c.Param("id") +func (h *CartHandler) Delete(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") - err := h.repository.Delete(c.Request.Context(), id) + err := h.repository.Delete(r.Context(), id) if err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - c.Status(http.StatusOK) return nil } @@ -178,13 +186,13 @@ func (h *CartHandler) Delete(c *gin.Context) error { // @Failure 404 {object} models.HTTPError // @Failure 500 {object} models.HTTPError // @Router /cart/{id}/item [post] -func (h *CartHandler) AddItem(c *gin.Context) error { - cartID := c.Param("id") +func (h *CartHandler) AddItem(w http.ResponseWriter, r *http.Request) error { + cartID := r.PathValue("id") var entity models.LineItem - if err := c.BindJSON(&entity); err != nil { + if err := json.NewDecoder(r.Body).Decode(&entity); err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - if err := h.repository.AddItem(c.Request.Context(), cartID, entity); err != nil { + if err := h.repository.AddItem(r.Context(), cartID, entity); err != nil { return models.NewHTTPError(http.StatusInternalServerError, err) } return nil @@ -205,9 +213,9 @@ func (h *CartHandler) AddItem(c *gin.Context) error { // @Failure 404 {object} models.HTTPError // @Failure 500 {object} models.HTTPError // @Router /cart/{id}/item/{itemID} [put] -func (h *CartHandler) UpdateItem(c *gin.Context) error { - cartID := c.Param("id") - itemID := c.Param("itemID") +func (h *CartHandler) UpdateItem(w http.ResponseWriter, r *http.Request) error { + cartID := r.PathValue("id") + itemID := r.PathValue("itemID") itemIDInt, err := strconv.Atoi(itemID) if err != nil { @@ -215,10 +223,10 @@ func (h *CartHandler) UpdateItem(c *gin.Context) error { } var entity models.LineItem - if err := c.BindJSON(&entity); err != nil { + if err := json.NewDecoder(r.Body).Decode(&entity); err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - if err := h.repository.UpdateItem(c.Request.Context(), cartID, itemIDInt, entity); err != nil { + if err := h.repository.UpdateItem(r.Context(), cartID, itemIDInt, entity); err != nil { return models.NewHTTPError(http.StatusInternalServerError, err) } return nil @@ -238,16 +246,16 @@ func (h *CartHandler) UpdateItem(c *gin.Context) error { // @Failure 404 {object} models.HTTPError // @Failure 500 {object} models.HTTPError // @Router /cart/{id}/item/{itemID} [delete] -func (h *CartHandler) DeleteItem(c *gin.Context) error { - cartID := c.Param("id") - itemID := c.Param("itemID") +func (h *CartHandler) DeleteItem(w http.ResponseWriter, r *http.Request) error { + cartID := r.PathValue("id") + itemID := r.PathValue("itemID") itemIDInt, err := strconv.Atoi(itemID) if err != nil { return models.NewHTTPError(http.StatusBadRequest, err) } - if err := h.repository.DeleteItem(c.Request.Context(), cartID, itemIDInt); err != nil { + if err := h.repository.DeleteItem(r.Context(), cartID, itemIDInt); err != nil { return models.NewHTTPError(http.StatusInternalServerError, err) } return nil diff --git a/src/backend/services/cart-api/internal/handlers/cart_handler_test.go b/src/backend/services/cart-api/internal/handlers/cart_handler_test.go index 7710faea3..4f419d9fe 100644 --- a/src/backend/services/cart-api/internal/handlers/cart_handler_test.go +++ b/src/backend/services/cart-api/internal/handlers/cart_handler_test.go @@ -5,14 +5,13 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" "github.com/google/uuid" - "github.com/gin-gonic/gin" "github.com/jurabek/cart-api/internal/models" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -74,7 +73,6 @@ func TestCartHandler(t *testing.T) { t.Skip() ctx := context.TODO() - gin.SetMode(gin.TestMode) customerBasket := models.Cart{ ID: uuid.New(), LineItems: items, @@ -85,27 +83,30 @@ func TestCartHandler(t *testing.T) { mockedBasketRepository.On("Get", ctx, "abcd").Return(&customerBasket, nil).Once() mockedBasketRepository.On("Get", ctx, "invalid").Return(&customerBasket, fmt.Errorf("Not found item with id: %s", "invalid")).Once() mockedBasketRepository.On("Update", ctx, &customerBasket).Return(nil) - var controller = NewCartHandler(mockedBasketRepository) + var handler = NewCartHandler(mockedBasketRepository) - router := gin.Default() - basket := router.Group("basket") - { - basket.GET(":id", ErrorHandler(controller.Get)) - basket.POST("", ErrorHandler(controller.Create)) - } + + mux := http.NewServeMux() + mux.HandleFunc("GET /basket/:id", ErrorHandler(handler.Get)) + mux.HandleFunc("POST /basket", ErrorHandler(handler.Create)) + + svr := httptest.NewServer(mux) + defer svr.Close() t.Run("Get should return ok when valid CustomerID", func(t *testing.T) { w := httptest.NewRecorder() - r, _ := http.NewRequest("GET", "/basket/abcd", nil) - router.ServeHTTP(w, r) - assert.Equal(t, http.StatusOK, w.Code) + r := httptest.NewRequest("GET", "/basket/abcd", nil) + ErrorHandler(handler.Get)(w, r) + res := w.Result() + assert.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("Get should return BadRequest when invalid CustomerID", func(t *testing.T) { w := httptest.NewRecorder() - r, _ := http.NewRequest("GET", "/basket/invalid", nil) - router.ServeHTTP(w, r) - assert.Equal(t, http.StatusBadRequest, w.Code) + r := httptest.NewRequest("GET", "/basket/invalid", nil) + ErrorHandler(handler.Get)(w, r) + res := w.Result() + assert.Equal(t, http.StatusBadRequest, res.StatusCode) }) t.Run("Create should create item and return ok", func(t *testing.T) { @@ -114,13 +115,17 @@ func TestCartHandler(t *testing.T) { body, _ := json.Marshal(customerBasket) w := httptest.NewRecorder() - r, _ := http.NewRequest("POST", "/basket", bytes.NewBuffer(body)) - router.ServeHTTP(w, r) + r:= httptest.NewRequest("POST", "/basket", bytes.NewBuffer(body)) - assert.Equal(t, http.StatusOK, w.Code) + ErrorHandler(handler.Create)(w, r) + + res := w.Result() + defer res.Body.Close() + + assert.Equal(t, http.StatusOK, res.StatusCode) var result models.Cart - bodyResult, _ := ioutil.ReadAll(w.Body) + bodyResult, _ := io.ReadAll(res.Body) _ = json.Unmarshal(bodyResult, &result) assert.Equal(t, result.ID, customerBasket.ID) @@ -135,9 +140,12 @@ func TestCartHandler(t *testing.T) { body, _ := json.Marshal(invalidCustomerBasket) w := httptest.NewRecorder() - r, _ := http.NewRequest("POST", "/basket", bytes.NewBuffer(body)) - router.ServeHTTP(w, r) - assert.Equal(t, http.StatusBadRequest, w.Code) + r := httptest.NewRequest("POST", "/basket", bytes.NewBuffer(body)) + + ErrorHandler(handler.Create)(w, r) + + res := w.Result() + assert.Equal(t, http.StatusBadRequest, res.StatusCode) }) t.Run("Create should create item and when could not find created item return code 400", func(t *testing.T) { @@ -151,8 +159,12 @@ func TestCartHandler(t *testing.T) { body, _ := json.Marshal(invalidCustomerBasket) w := httptest.NewRecorder() - r, _ := http.NewRequest("POST", "/basket", bytes.NewBuffer(body)) - router.ServeHTTP(w, r) - assert.Equal(t, http.StatusBadRequest, w.Code) + r := httptest.NewRequest("POST", "/basket", bytes.NewBuffer(body)) + + ErrorHandler(handler.Create)(w, r) + + res := w.Result() + + assert.Equal(t, http.StatusBadRequest, res.StatusCode) }) } diff --git a/src/backend/services/cart-api/internal/instrumentation/instrumentation.go b/src/backend/services/cart-api/internal/instrumentation/instrumentation.go new file mode 100644 index 000000000..3d24b8195 --- /dev/null +++ b/src/backend/services/cart-api/internal/instrumentation/instrumentation.go @@ -0,0 +1,120 @@ +package instrumentation + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/rs/zerolog/log" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +type CloseFunc func() + +func StartOTEL(ctx context.Context) (CloseFunc, error) { + res, err := resource.New(ctx, + resource.WithAttributes( + // the service name used to display traces in backends + semconv.ServiceName("cart-api"), + semconv.ServiceVersion("v1"), + ), + ) + if err != nil { + return nil, fmt.Errorf("failed to create resource: %w", err) + } + + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + + otelExportEndpoint := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") + if otelExportEndpoint == "" { + otelExportEndpoint = "localhost:4317" + } + conn, err := grpc.DialContext(ctx, otelExportEndpoint, + // Note the use of insecure transport here. TLS is recommended in production. + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + if err != nil { + return nil, fmt.Errorf("failed to create gRPC connection to collector: %w", err) + } + + meterProvider, err := setupMeterProvider(ctx, conn, res) + if err != nil { + return nil, err + } + + traceProvider, err := setupTraceProvider(ctx, conn, res) + if err != nil { + return nil, err + } + + closeFunc := func() { + // Handle shutdown properly so nothing leaks. + if meterErr := meterProvider.Shutdown(ctx ); meterErr != nil { + log.Error().Msg(meterErr.Error()) + } + + if tpErr := traceProvider.Shutdown(ctx); tpErr != nil { + log.Error().Err(tpErr) + } + + if connErr := conn.Close(); connErr != nil { + log.Error().Err(connErr) + } + } + + return closeFunc, nil +} + +func setupMeterProvider(ctx context.Context, conn *grpc.ClientConn, res *resource.Resource) (*metric.MeterProvider, error) { + // Create a meter provider. + // You can pass this instance directly to your instrumented code if it + // accepts a MeterProvider instance. + metricExporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(conn)) + if err != nil { + return nil, err + } + + meterProvider := metric.NewMeterProvider( + metric.WithResource(res), + metric.WithReader(metric.NewPeriodicReader(metricExporter, + // Default is 1m. Set to 3s for demonstrative purposes. + metric.WithInterval(10*time.Second))), + ) + + // Register as global meter provider so that it can be used via otel.Meter + // and accessed using otel.GetMeterProvider. + // Most instrumentation libraries use the global meter provider as default. + // If the global meter provider is not set then a no-op implementation + // is used, which fails to generate data. + otel.SetMeterProvider(meterProvider) + return meterProvider, nil +} + +func setupTraceProvider(ctx context.Context, conn *grpc.ClientConn, res *resource.Resource) (*sdktrace.TracerProvider, error) { + // Set up a trace exporter + traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithGRPCConn(conn)) + if err != nil { + return nil, fmt.Errorf("failed to create trace exporter: %w", err) + } + + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(res), + sdktrace.WithBatcher(traceExporter), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + return tp, nil +} diff --git a/src/backend/services/cart-api/internal/middlewares/swagger.go b/src/backend/services/cart-api/internal/middlewares/swagger.go deleted file mode 100644 index a3f1a7cd1..000000000 --- a/src/backend/services/cart-api/internal/middlewares/swagger.go +++ /dev/null @@ -1,31 +0,0 @@ -package middlewares - -import ( - "os" - - "github.com/gin-gonic/gin" - "github.com/jurabek/cart-api/internal/docs" - "github.com/rs/zerolog/log" -) - -// RequestMiddleware changes swagger Info on runtime -func RequestMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - for key, val := range c.Request.Header { - log.Printf("Header %s: %s", key, val) - } - log.Printf("Request: %s\r\n", c.Request.RequestURI) - - basePath, _ := os.LookupEnv("BASE_PATH") - docs.SwaggerInfo.BasePath = basePath + "/api/v1/" - log.Printf("Swagger base path: %s\r\n", docs.SwaggerInfo.BasePath) - - docs.SwaggerInfo.Host = "localhost" - - if forwardedHost := c.Request.Header["X-Forwarded-Host"]; forwardedHost != nil { - docs.SwaggerInfo.Host = forwardedHost[0] - log.Printf("Swagger host: %s\r\n", docs.SwaggerInfo.Host) - } - c.Next() - } -}