diff --git a/.gitignore b/.gitignore index ddc19ad..553b044 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .vscode bin .coverage -allure-results \ No newline at end of file +allure-results +vendor-proto/* \ No newline at end of file diff --git a/Makefile b/Makefile index 87b046e..eb6193d 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ include make/generate.mk PKGS = $(shell go list ./... | grep -vE 'mock|config|generated|header|document|internal/pb') INTEGRATION_TAG = integration +.PHONY: lint, coverage + lint: cart-lint loms-lint notifier-lint comments-lint build: cart-build loms-build notifier-build comments-build @@ -13,15 +15,20 @@ build: cart-build loms-build notifier-build comments-build coverage: cart-coverage loms-coverage notifier-coverage comments-coverage generate: cart-generate loms-generate notifier-generate comments-generate + cd pkg && go mod tidy run-all: echo "starting build" docker-compose up --build +.PHONY: .integration-test integration-test: - ALLURE_OUTPUT_PATH=$(shell pwd) go test -v -tags=$(INTEGRATION_TAG) ./cart/tests/integration + ALLURE_OUTPUT_PATH=$(shell pwd)/allure-results ALLURE_OUTPUT_FOLDER=cart go test -v -tags=$(INTEGRATION_TAG) ./cart/tests/integration + ALLURE_OUTPUT_PATH=$(shell pwd)/allure-results ALLURE_OUTPUT_FOLDER=loms go test -v -tags=$(INTEGRATION_TAG) ./loms/tests/integration bench: go test -bench=BenchmarkInMemoryRepository -benchmem ./cart/internal/domain/cart/repository -benchtime 3s -.PHONY: lint, coverage +.PHONY: .serve-swagger +.serve-swagger: + bin/swagger serve api/openapiv2/loms/v1/loms.swagger.json --no-open diff --git a/api/loms/v1/loms.proto b/api/loms/v1/loms.proto new file mode 100644 index 0000000..f162350 --- /dev/null +++ b/api/loms/v1/loms.proto @@ -0,0 +1,125 @@ +syntax = "proto3"; + +import "google/protobuf/empty.proto"; +import "validate/validate.proto"; +import "google/api/annotations.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; + +option go_package = "route256/pkg/api/loms/v1;loms"; + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "LOMS Service"; + version: "1.0.0"; + }; + schemes: HTTP; + schemes: HTTPS; + consumes: "application/json"; + produces: "application/json"; +}; + +service LOMS { + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag) = { + description: "LOMS Service" + external_docs: { + url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/proto/examplepb/a_bit_of_everything.proto"; + description: "Find out more about grpc-gateway"; + } + }; + + rpc OrderCreate(OrderCreateRequest) returns (OrderCreateResponse) { + option(google.api.http) = { + post: "/order/create" + body: "*" + }; + } + + rpc OrderInfo(OrderInfoRequest) returns (OrderInfoResponse) { + option (google.api.http) = { + get: "/order/info" + }; + } + + rpc OrderPay(OrderPayRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post: "/order/pay" + body: "*" + }; + } + + rpc OrderCancel(OrderCancelRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post: "/order/cancel" + body: "*" + }; + } + + rpc StocksInfo(StocksInfoRequest) returns (StocksInfoResponse) { + option (google.api.http) = { + get: "/stock/info" + }; + } +} + +message OrderItem { + int64 sku = 1 [(validate.rules).int64 = {gt: 0}]; + uint32 count = 2 [(validate.rules).uint32 = {gt: 0}]; +} + +// OrderCreate + +message OrderCreateRequest { + int64 user_id = 1 [ + (validate.rules).int64 = {gt: 0} + ]; + repeated OrderItem items = 2 [ + (validate.rules).repeated = {min_items: 1} + ]; +} + +message OrderCreateResponse { + int64 orderId = 1; +} + +// OrderInfo + +message OrderInfoRequest { + int64 orderId = 1 [(validate.rules).int64 = {gt: 0}]; +} + +message OrderInfoResponse { + string status = 1; + int64 user_id = 2; + repeated OrderItem items = 3; +} + +enum OrderStatus { + ORDER_STATUS_UNSPECIFIED = 0; + ORDER_STATUS_NEW = 1; + ORDER_STATUS_AWAITING_PAYMENT = 2; + ORDER_STATUS_FAILED = 3; + ORDER_STATUS_PAYED = 4; + ORDER_STATUS_CANCELLED = 5; +} + +// OrderPay + +message OrderPayRequest { + int64 order_id = 1 [(validate.rules).int64 = {gt: 0}]; +} + +// OrderCancel + +message OrderCancelRequest { + int64 order_id = 1 [(validate.rules).int64 = {gt: 0}]; +} + +// StocksInfo + +message StocksInfoRequest { + int64 sku = 1 [(validate.rules).int64 = {gt: 0}]; +} + +message StocksInfoResponse { + uint32 count = 1; +} diff --git a/api/openapiv2/loms/v1/loms.swagger.json b/api/openapiv2/loms/v1/loms.swagger.json new file mode 100644 index 0000000..c093856 --- /dev/null +++ b/api/openapiv2/loms/v1/loms.swagger.json @@ -0,0 +1,303 @@ +{ + "swagger": "2.0", + "info": { + "title": "LOMS Service", + "version": "1.0.0" + }, + "tags": [ + { + "name": "LOMS", + "description": "LOMS Service", + "externalDocs": { + "description": "Find out more about grpc-gateway", + "url": "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/proto/examplepb/a_bit_of_everything.proto" + } + } + ], + "schemes": [ + "http", + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/order/cancel": { + "post": { + "operationId": "LOMS_OrderCancel", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/OrderCancelRequest" + } + } + ], + "tags": [ + "LOMS" + ] + } + }, + "/order/create": { + "post": { + "operationId": "LOMS_OrderCreate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/OrderCreateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/OrderCreateRequest" + } + } + ], + "tags": [ + "LOMS" + ] + } + }, + "/order/info": { + "get": { + "operationId": "LOMS_OrderInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/OrderInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "orderId", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + } + ], + "tags": [ + "LOMS" + ] + } + }, + "/order/pay": { + "post": { + "operationId": "LOMS_OrderPay", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "type": "object", + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/OrderPayRequest" + } + } + ], + "tags": [ + "LOMS" + ] + } + }, + "/stock/info": { + "get": { + "operationId": "LOMS_StocksInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/StocksInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "sku", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + } + ], + "tags": [ + "LOMS" + ] + } + } + }, + "definitions": { + "OrderCancelRequest": { + "type": "object", + "properties": { + "orderId": { + "type": "string", + "format": "int64" + } + } + }, + "OrderCreateRequest": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "format": "int64" + }, + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/OrderItem" + } + } + } + }, + "OrderCreateResponse": { + "type": "object", + "properties": { + "orderId": { + "type": "string", + "format": "int64" + } + } + }, + "OrderInfoResponse": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "userId": { + "type": "string", + "format": "int64" + }, + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/OrderItem" + } + } + } + }, + "OrderItem": { + "type": "object", + "properties": { + "sku": { + "type": "string", + "format": "int64" + }, + "count": { + "type": "integer", + "format": "int64" + } + } + }, + "OrderPayRequest": { + "type": "object", + "properties": { + "orderId": { + "type": "string", + "format": "int64" + } + } + }, + "StocksInfoResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer", + "format": "int64" + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/cart/Dockerfile b/cart/Dockerfile index 051d65e..6848386 100644 --- a/cart/Dockerfile +++ b/cart/Dockerfile @@ -1,19 +1,21 @@ -FROM golang:1.23.1-alpine as builder +FROM golang:1.23.9-alpine as builder WORKDIR /build -COPY go.mod go.mod -COPY go.sum go.sum +COPY cart/go.mod go.mod +COPY cart/go.sum go.sum RUN go mod download COPY . . +WORKDIR cart + RUN CGO_ENABLED=0 GOOS=linux go build -o /server ./cmd/server/main.go FROM scratch COPY --from=builder server /bin/server -COPY configs/values_local.yaml /bin/config/values_local.yaml +COPY cart/configs/values_local.yaml /bin/config/values_local.yaml ENV CONFIG_FILE=/bin/config/values_local.yaml diff --git a/cart/go.mod b/cart/go.mod index 902f551..c1a72f3 100644 --- a/cart/go.mod +++ b/cart/go.mod @@ -5,6 +5,7 @@ go 1.23.9 require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 + google.golang.org/grpc v1.72.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/cart/go.sum b/cart/go.sum index d738f81..86da82c 100644 --- a/cart/go.sum +++ b/cart/go.sum @@ -54,6 +54,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gojuno/minimock/v3 v3.4.5 h1:Jcb0tEYZvVlQNtAAYpg3jCOoSwss2c1/rNugYTzj304= github.com/gojuno/minimock/v3 v3.4.5/go.mod h1:o9F8i2IT8v3yirA7mmdpNGzh1WNesm6iQakMtQV6KiE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -147,6 +149,8 @@ go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCRE go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= diff --git a/cart/internal/app/app.go b/cart/internal/app/app.go index 3ce8ba5..0d4221e 100644 --- a/cart/internal/app/app.go +++ b/cart/internal/app/app.go @@ -9,14 +9,19 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "route256/cart/internal/app/server" - "route256/cart/internal/domain/cart/repository" - "route256/cart/internal/domain/cart/service" - product_service "route256/cart/internal/domain/products/service" + loms_service "route256/cart/internal/clients/loms" + product_service "route256/cart/internal/clients/products" + "route256/cart/internal/domain/repository" + "route256/cart/internal/domain/service" "route256/cart/internal/infra/config" "route256/cart/internal/infra/http/middlewares" "route256/cart/internal/infra/http/round_trippers" + + pbLOMS "route256/pkg/api/loms/v1" ) const ( @@ -39,9 +44,9 @@ func NewApp(configPath string) (*App, error) { zerolog.SetGlobalLevel(zerolog.InfoLevel) if c.Service.LogLevel != "" { - level, err := zerolog.ParseLevel(c.Service.LogLevel) - if err != nil { - return nil, fmt.Errorf("unknown log level `%s` provided: %w", c.Service.LogLevel, err) + level, logErr := zerolog.ParseLevel(c.Service.LogLevel) + if logErr != nil { + return nil, fmt.Errorf("unknown log level `%s` provided: %w", c.Service.LogLevel, logErr) } zerolog.SetGlobalLevel(level) @@ -52,7 +57,13 @@ func NewApp(configPath string) (*App, error) { app := &App{ config: c, } - app.server.Handler = app.BootstrapHandlers(app.setupCartService()) + + service, err := app.setupCartService() + if err != nil { + return nil, err + } + + app.server.Handler = app.BootstrapHandlers(service) return app, nil } @@ -70,7 +81,8 @@ func (app *App) ListenAndServe() error { return app.server.Serve(l) } -func (app *App) setupCartService() *service.CartService { +func (app *App) setupCartService() (*service.CartService, error) { + // Product service client transport := http.DefaultTransport transport = round_trippers.NewLogRoundTripper(transport) transport = round_trippers.NewRetryRoundTripper(transport, productsRetryAttemptsDefault, productsInitialDelaySecDefault) @@ -86,10 +98,21 @@ func (app *App) setupCartService() *service.CartService { fmt.Sprintf("%s:%s", app.config.ProductService.Host, app.config.ProductService.Port), ) + // LOMS service client + conn, err := grpc.NewClient( + fmt.Sprintf("%s:%s", app.config.LomsService.Host, app.config.LomsService.Port), + grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, fmt.Errorf("grpc.NewClient: %w", err) + } + + lomsClient := pbLOMS.NewLOMSClient(conn) + lomsService := loms_service.NewLomsService(lomsClient) + const userCartCap = 100 cartRepository := repository.NewInMemoryRepository(userCartCap) - return service.NewCartService(cartRepository, productService) + return service.NewCartService(cartRepository, productService, lomsService), nil } func (app *App) BootstrapHandlers(cartService *service.CartService) http.Handler { @@ -97,6 +120,7 @@ func (app *App) BootstrapHandlers(cartService *service.CartService) http.Handler mx := http.NewServeMux() mx.HandleFunc("POST /user/{user_id}/cart/{sku_id}", s.AddItemHandler) + mx.HandleFunc("POST /checkout/{user_id}", s.CheckoutHandler) mx.HandleFunc("GET /user/{user_id}/cart", s.GetItemsByUserIDHandler) mx.HandleFunc("DELETE /user/{user_id}/cart/{sku_id}", s.DeleteItemHandler) mx.HandleFunc("DELETE /user/{user_id}/cart", s.DeleteItemsByUserIDHandler) diff --git a/cart/internal/app/server/add_item_handler.go b/cart/internal/app/server/add_item_handler.go index 7d7e390..c07e87d 100644 --- a/cart/internal/app/server/add_item_handler.go +++ b/cart/internal/app/server/add_item_handler.go @@ -13,12 +13,12 @@ import ( "github.com/rs/zerolog/log" ) -type CreateReviewRequest struct { +type AddItemRequest struct { Count uint32 `json:"count" validate:"required,gt=0"` } func (s *Server) AddItemHandler(w http.ResponseWriter, r *http.Request) { - var request CreateReviewRequest + var request AddItemRequest if err := json.NewDecoder(r.Body).Decode(&request); err != nil { makeErrorResponse(w, err, http.StatusBadRequest) @@ -79,7 +79,7 @@ func (s *Server) AddItemHandler(w http.ResponseWriter, r *http.Request) { if err := s.cartService.AddItem(r.Context(), uid, item); err != nil { switch { - case errors.Is(err, model.ErrProductNotFound): + case errors.Is(err, model.ErrProductNotFound), errors.Is(err, model.ErrNotEnoughStocks): makeErrorResponse(w, err, http.StatusPreconditionFailed) log.Trace().Err(err).Msgf("product does not exist") diff --git a/cart/internal/app/server/checkout_handler.go b/cart/internal/app/server/checkout_handler.go new file mode 100644 index 0000000..e187d2f --- /dev/null +++ b/cart/internal/app/server/checkout_handler.go @@ -0,0 +1,58 @@ +package server + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "strconv" + + "route256/cart/internal/domain/entity" + "route256/cart/internal/domain/model" + + "github.com/rs/zerolog/log" +) + +type CheckoutResponse struct { + OrderID int64 `json:"order_id"` +} + +func (s *Server) CheckoutHandler(w http.ResponseWriter, r *http.Request) { + strUserID := r.PathValue("user_id") + userID, err := strconv.ParseInt(strUserID, 10, 64) + if err != nil || userID <= 0 { + if err == nil { + err = fmt.Errorf("user_id must be greater than 0") + } + + makeErrorResponse(w, err, http.StatusBadRequest) + + log.Trace().Err(err).Msgf("user_id=`%s`", strUserID) + + return + } + + orderID, err := s.cartService.CheckoutUserCart(r.Context(), entity.UID(userID)) + switch { + case errors.Is(err, model.ErrCartNotFound): + makeErrorResponse(w, err, http.StatusNotFound) + + return + case err != nil: + makeErrorResponse(w, err, http.StatusInternalServerError) + + return + } + + resp := CheckoutResponse{ + OrderID: orderID, + } + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + if err := json.NewEncoder(w).Encode(resp); err != nil { + makeErrorResponse(w, err, http.StatusInternalServerError) + + return + } +} diff --git a/cart/internal/app/server/server.go b/cart/internal/app/server/server.go index 336ef09..8977830 100644 --- a/cart/internal/app/server/server.go +++ b/cart/internal/app/server/server.go @@ -12,6 +12,7 @@ type CartService interface { GetItemsByUserID(ctx context.Context, userID entity.UID) (*model.Cart, error) DeleteItem(ctx context.Context, userID entity.UID, sku entity.Sku) error DeleteItemsByUserID(ctx context.Context, userID entity.UID) error + CheckoutUserCart(ctx context.Context, userID entity.UID) (int64, error) } type Server struct { diff --git a/cart/internal/clients/loms/service.go b/cart/internal/clients/loms/service.go new file mode 100644 index 0000000..dcfef2a --- /dev/null +++ b/cart/internal/clients/loms/service.go @@ -0,0 +1,56 @@ +package loms + +import ( + "context" + "fmt" + + "route256/cart/internal/domain/entity" + "route256/cart/internal/domain/model" + + pbLoms "route256/pkg/api/loms/v1" +) + +type Service struct { + grpcClient pbLoms.LOMSClient +} + +func NewLomsService(grpcClient pbLoms.LOMSClient) *Service { + return &Service{ + grpcClient: grpcClient, + } +} + +func (s *Service) OrderCreate(ctx context.Context, cart *model.Cart) (int64, error) { + items := make([]*pbLoms.OrderItem, len(cart.Items)) + for i, item := range cart.Items { + items[i] = &pbLoms.OrderItem{ + Sku: int64(item.Product.Sku), + Count: item.Count, + } + } + + req := &pbLoms.OrderCreateRequest{ + UserId: int64(cart.UserID), + Items: items, + } + + resp, err := s.grpcClient.OrderCreate(ctx, req) + if err != nil { + return 0, fmt.Errorf("grpcClient.OrderCreate: %w", err) + } + + return resp.OrderId, nil +} + +func (s *Service) StocksInfo(ctx context.Context, sku entity.Sku) (uint32, error) { + req := &pbLoms.StocksInfoRequest{ + Sku: int64(sku), + } + + resp, err := s.grpcClient.StocksInfo(ctx, req) + if err != nil { + return 0, fmt.Errorf("grpcClient.StocksInfo: %w", err) + } + + return resp.Count, nil +} diff --git a/cart/internal/domain/products/service/product_service.go b/cart/internal/clients/products/service.go similarity index 98% rename from cart/internal/domain/products/service/product_service.go rename to cart/internal/clients/products/service.go index de3bcfe..d945700 100644 --- a/cart/internal/domain/products/service/product_service.go +++ b/cart/internal/clients/products/service.go @@ -1,4 +1,4 @@ -package service +package products import ( "context" diff --git a/cart/internal/domain/entity/cart.go b/cart/internal/domain/entity/cart.go index 0c6d2ca..1b7f317 100644 --- a/cart/internal/domain/entity/cart.go +++ b/cart/internal/domain/entity/cart.go @@ -1,7 +1,7 @@ package entity type ( - UID uint64 + UID int64 Sku int64 ) diff --git a/cart/internal/domain/model/errors.go b/cart/internal/domain/model/errors.go index 391a118..c01c17b 100644 --- a/cart/internal/domain/model/errors.go +++ b/cart/internal/domain/model/errors.go @@ -4,6 +4,7 @@ import "errors" var ( ErrProductNotFound = errors.New("invalid sku") + ErrNotEnoughStocks = errors.New("not enough stocks") ErrCartNotFound = errors.New("cart not found") ErrItemNotFoundInCart = errors.New("item not found in cart") diff --git a/cart/internal/domain/cart/repository/in_memory_repository.go b/cart/internal/domain/repository/in_memory_repository.go similarity index 100% rename from cart/internal/domain/cart/repository/in_memory_repository.go rename to cart/internal/domain/repository/in_memory_repository.go diff --git a/cart/internal/domain/cart/repository/in_memory_repository_bench_test.go b/cart/internal/domain/repository/in_memory_repository_bench_test.go similarity index 100% rename from cart/internal/domain/cart/repository/in_memory_repository_bench_test.go rename to cart/internal/domain/repository/in_memory_repository_bench_test.go diff --git a/cart/internal/domain/cart/repository/in_memory_repository_test.go b/cart/internal/domain/repository/in_memory_repository_test.go similarity index 100% rename from cart/internal/domain/cart/repository/in_memory_repository_test.go rename to cart/internal/domain/repository/in_memory_repository_test.go diff --git a/cart/internal/domain/cart/service/mock/repository_mock.go b/cart/internal/domain/service/mock/repository_mock.go similarity index 100% rename from cart/internal/domain/cart/service/mock/repository_mock.go rename to cart/internal/domain/service/mock/repository_mock.go diff --git a/cart/internal/domain/cart/service/service.go b/cart/internal/domain/service/service.go similarity index 80% rename from cart/internal/domain/cart/service/service.go rename to cart/internal/domain/service/service.go index 338f2f6..37b0d17 100644 --- a/cart/internal/domain/cart/service/service.go +++ b/cart/internal/domain/service/service.go @@ -6,10 +6,10 @@ import ( "slices" "sync" + "github.com/rs/zerolog/log" + "route256/cart/internal/domain/entity" "route256/cart/internal/domain/model" - - "github.com/rs/zerolog/log" ) //go:generate minimock -i Repository -o ./mock -s _mock.go @@ -24,15 +24,23 @@ type ProductService interface { GetProductBySku(ctx context.Context, sku entity.Sku) (*model.Product, error) } -type CartService struct { - repository Repository - productService ProductService +type LomsService interface { + OrderCreate(ctx context.Context, cart *model.Cart) (int64, error) + StocksInfo(ctx context.Context, sku entity.Sku) (uint32, error) } -func NewCartService(repository Repository, productService ProductService) *CartService { +type CartService struct { + repository Repository + + productService ProductService + lomsService LomsService +} + +func NewCartService(repository Repository, productService ProductService, lomsService LomsService) *CartService { return &CartService{ repository: repository, productService: productService, + lomsService: lomsService, } } @@ -50,6 +58,15 @@ func (s *CartService) AddItem(ctx context.Context, userID entity.UID, item *mode return fmt.Errorf("productService.GetProductBySku: %w", err) } + count, err := s.lomsService.StocksInfo(ctx, item.Product.Sku) + if err != nil { + return fmt.Errorf("lomsService.StocksInfo: %w", err) + } + + if count < item.Count { + return model.ErrNotEnoughStocks + } + if err := s.repository.AddItem(ctx, userID, item); err != nil { return fmt.Errorf("repository.AddItemToCart: %w", err) } @@ -170,3 +187,25 @@ func (s *CartService) DeleteItemsByUserID(ctx context.Context, userID entity.UID return nil } + +func (s *CartService) CheckoutUserCart(ctx context.Context, userID entity.UID) (int64, error) { + if userID <= 0 { + return 0, fmt.Errorf("userID invalid") + } + + cart, err := s.GetItemsByUserID(ctx, entity.UID(userID)) + if err != nil { + return 0, err + } + + orderID, err := s.lomsService.OrderCreate(ctx, cart) + if err != nil { + return 0, fmt.Errorf("lomsService.OrderCreate: %w", err) + } + + if err := s.DeleteItemsByUserID(ctx, userID); err != nil { + return 0, err + } + + return orderID, nil +} diff --git a/cart/internal/domain/cart/service/service_test.go b/cart/internal/domain/service/service_test.go similarity index 69% rename from cart/internal/domain/cart/service/service_test.go rename to cart/internal/domain/service/service_test.go index 49aacf1..c42b168 100644 --- a/cart/internal/domain/cart/service/service_test.go +++ b/cart/internal/domain/service/service_test.go @@ -9,9 +9,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "route256/cart/internal/domain/cart/service/mock" "route256/cart/internal/domain/entity" "route256/cart/internal/domain/model" + "route256/cart/internal/domain/service/mock" ) const ( @@ -19,9 +19,9 @@ const ( validName = "some product name" ) -type ProductServiceFake struct{} +type productServiceFake struct{} -func (f *ProductServiceFake) GetProductBySku(_ context.Context, sku entity.Sku) (*model.Product, error) { +func (f *productServiceFake) GetProductBySku(_ context.Context, sku entity.Sku) (*model.Product, error) { if sku%2 == 0 { return nil, errors.New("empty shelf") } @@ -33,6 +33,24 @@ func (f *ProductServiceFake) GetProductBySku(_ context.Context, sku entity.Sku) }, nil } +type lomsServiceFake struct{} + +func (f *lomsServiceFake) StocksInfo(_ context.Context, sku entity.Sku) (uint32, error) { + if sku == 1111 { + return 0, errors.New("stock error") + } + + return 100, nil +} + +func (f *lomsServiceFake) OrderCreate(_ context.Context, cart *model.Cart) (int64, error) { + if cart.UserID == 1111 { + return 0, errors.New("order create error") + } + + return 1234, nil +} + func TestCartService_AddItem(t *testing.T) { t.Parallel() @@ -49,9 +67,20 @@ func TestCartService_AddItem(t *testing.T) { Count: 1, } + testSKULomsFailing := entity.Sku(1111) + testItemLomsFailing := model.Item{ + Product: &model.Product{ + Name: validName, + Price: validPrice, + Sku: testSKULomsFailing, + }, + Count: 1, + } + type fields struct { repository Repository productService ProductService + lomsService LomsService } type args struct { ctx context.Context @@ -72,7 +101,8 @@ func TestCartService_AddItem(t *testing.T) { AddItemMock. Expect(ctx, 1337, &testItem). Return(nil), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, }, args: args{ ctx: ctx, @@ -118,7 +148,8 @@ func TestCartService_AddItem(t *testing.T) { name: "product service error", fields: fields{ repository: nil, - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, }, args: args{ ctx: ctx, @@ -141,7 +172,8 @@ func TestCartService_AddItem(t *testing.T) { AddItemMock. Expect(ctx, 1337, &testItem). Return(assert.AnError), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, }, args: args{ ctx: ctx, @@ -150,6 +182,41 @@ func TestCartService_AddItem(t *testing.T) { }, wantErr: require.Error, }, + { + name: "stocks acquiring error", + fields: fields{ + repository: nil, + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, + }, + args: args{ + ctx: ctx, + item: &testItemLomsFailing, + userID: 1337, + }, + wantErr: require.Error, + }, + { + name: "not enough stocks", + fields: fields{ + repository: nil, + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, + }, + args: args{ + ctx: ctx, + item: &model.Item{ + Product: &model.Product{ + Name: validName, + Price: validPrice, + Sku: testSKU, + }, + Count: 10000, + }, + userID: 1337, + }, + wantErr: require.Error, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -158,6 +225,7 @@ func TestCartService_AddItem(t *testing.T) { s := &CartService{ repository: tt.fields.repository, productService: tt.fields.productService, + lomsService: tt.fields.lomsService, } err := s.AddItem(tt.args.ctx, tt.args.userID, tt.args.item) @@ -218,7 +286,7 @@ func TestCartService_GetItemsByUserID(t *testing.T) { GetItemsByUserIDMock. Expect(ctx, testUID). Return(testEntityCart, nil), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, }, args: args{ ctx: ctx, @@ -238,7 +306,7 @@ func TestCartService_GetItemsByUserID(t *testing.T) { Items: []entity.Sku{testSKU}, ItemCount: map[entity.Sku]uint32{testSKU: 2}, }, nil), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, }, args: args{ ctx: ctx, @@ -271,7 +339,7 @@ func TestCartService_GetItemsByUserID(t *testing.T) { Items: []entity.Sku{testSKU, 1}, ItemCount: map[entity.Sku]uint32{testSKU: 1, 1: 1}, }, nil), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, }, args: args{ ctx: ctx, @@ -357,7 +425,7 @@ func TestCartService_GetItemsByUserID(t *testing.T) { Items: []entity.Sku{2}, ItemCount: map[entity.Sku]uint32{2: 1}, }, nil), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, }, args: args{ ctx: ctx, @@ -377,7 +445,7 @@ func TestCartService_GetItemsByUserID(t *testing.T) { Items: []entity.Sku{2}, ItemCount: map[entity.Sku]uint32{2: 1}, }, nil), - productService: &ProductServiceFake{}, + productService: &productServiceFake{}, }, args: args{ ctx: ctx, @@ -573,3 +641,118 @@ func TestCartService_DeleteItemsByUserID(t *testing.T) { }) } } + +func TestCartService_CheckoutUserCart(t *testing.T) { + t.Parallel() + + ctx := context.Background() + mc := minimock.NewController(t) + + testSKU := entity.Sku(199) + testCart := entity.Cart{ + Items: []entity.Sku{testSKU}, + ItemCount: map[entity.Sku]uint32{testSKU: 1}, + } + + type fields struct { + repository Repository + productService ProductService + lomsService LomsService + } + + type args struct { + ctx context.Context + userID entity.UID + } + + tests := []struct { + name string + fields fields + args args + wantOrderID int64 + wantErr require.ErrorAssertionFunc + }{ + { + name: "success", + fields: fields{ + repository: mock.NewRepositoryMock(mc). + GetItemsByUserIDMock. + Expect(ctx, 1337). + Return(testCart, nil). + DeleteItemsByUserIDMock. + Expect(ctx, 1337). + Return(nil), + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, + }, + args: args{ctx: ctx, userID: 1337}, + wantOrderID: 1234, + wantErr: require.NoError, + }, + { + name: "invalid user id", + fields: fields{}, + args: args{ctx: ctx, userID: 0}, + wantErr: require.Error, + }, + { + name: "get cart error", + fields: fields{ + repository: mock.NewRepositoryMock(mc). + GetItemsByUserIDMock. + Expect(ctx, 1337). + Return(entity.Cart{}, assert.AnError), + }, + args: args{ctx: ctx, userID: 1337}, + wantErr: require.Error, + }, + { + name: "order create error", + fields: fields{ + repository: mock.NewRepositoryMock(mc). + GetItemsByUserIDMock. + Expect(ctx, 1111). + Return(testCart, nil), + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, + }, + args: args{ctx: ctx, userID: 1111}, + wantErr: require.Error, + }, + { + name: "delete order error", + fields: fields{ + repository: mock.NewRepositoryMock(mc). + GetItemsByUserIDMock. + Expect(ctx, 1337). + Return(testCart, nil). + DeleteItemsByUserIDMock. + Expect(ctx, 1337). + Return(assert.AnError), + productService: &productServiceFake{}, + lomsService: &lomsServiceFake{}, + }, + args: args{ctx: ctx, userID: 1337}, + wantErr: require.Error, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + svc := &CartService{ + repository: tt.fields.repository, + productService: tt.fields.productService, + lomsService: tt.fields.lomsService, + } + + orderID, err := svc.CheckoutUserCart(tt.args.ctx, tt.args.userID) + tt.wantErr(t, err) + if err == nil { + require.Equal(t, tt.wantOrderID, orderID) + } + }) + } +} diff --git a/cart/tests/integration/cart_integration_test.go b/cart/tests/integration/cart_integration_test.go index 16e59a0..df7ee57 100644 --- a/cart/tests/integration/cart_integration_test.go +++ b/cart/tests/integration/cart_integration_test.go @@ -7,6 +7,7 @@ import ( "context" "encoding/json" "fmt" + "net" "net/http" "net/http/httptest" "testing" @@ -16,13 +17,17 @@ import ( "github.com/ozontech/allure-go/pkg/framework/suite" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + "google.golang.org/grpc" + lomsService "route256/cart/internal/adapter/client/loms" + productsService "route256/cart/internal/adapter/client/products" "route256/cart/internal/app" - "route256/cart/internal/domain/cart/repository" - cartService "route256/cart/internal/domain/cart/service" "route256/cart/internal/domain/entity" "route256/cart/internal/domain/model" - productsService "route256/cart/internal/domain/products/service" + "route256/cart/internal/domain/repository" + cartService "route256/cart/internal/domain/service" + + pbLoms "route256/pkg/api/loms/v1" ) const ( @@ -34,12 +39,27 @@ const ( testUID = entity.UID(1337) ) +type lomsServerMock struct { + pbLoms.UnimplementedLOMSServer +} + +func (lomsServerMock) OrderCreate(_ context.Context, _ *pbLoms.OrderCreateRequest) (*pbLoms.OrderCreateResponse, error) { + return &pbLoms.OrderCreateResponse{OrderId: 1}, nil +} + +func (lomsServerMock) StocksInfo(_ context.Context, _ *pbLoms.StocksInfoRequest) (*pbLoms.StocksInfoResponse, error) { + return &pbLoms.StocksInfoResponse{Count: 1000}, nil +} + type CartHandlerSuite struct { suite.Suite psContainer testcontainers.Container - server *httptest.Server + lomsSrv *grpc.Server + lomsConn *grpc.ClientConn + + server *httptest.Server cartSvc *cartService.CartService } @@ -72,6 +92,20 @@ func (s *CartHandlerSuite) BeforeAll(t provider.T) { productURL = endpoint }) + t.WithNewStep("start loms grpc server", func(st provider.StepCtx) { + lis, err := net.Listen("tcp", "127.0.0.1:0") + st.Require().NoError(err) + + s.lomsSrv = grpc.NewServer() + pbLoms.RegisterLOMSServer(s.lomsSrv, &lomsServerMock{}) + + go s.lomsSrv.Serve(lis) + + conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure(), grpc.WithBlock()) + st.Require().NoError(err) + s.lomsConn = conn + }) + t.WithNewStep("init cart-service", func(sCtx provider.StepCtx) { prodClient := productsService.NewProductService( *http.DefaultClient, @@ -79,8 +113,10 @@ func (s *CartHandlerSuite) BeforeAll(t provider.T) { productURL, ) + lomsClient := pbLoms.NewLOMSClient(s.lomsConn) + repo := repository.NewInMemoryRepository(10) - s.cartSvc = cartService.NewCartService(repo, prodClient) + s.cartSvc = cartService.NewCartService(repo, prodClient, lomsService.NewLomsService(lomsClient)) appSrv := &app.App{} @@ -89,8 +125,11 @@ func (s *CartHandlerSuite) BeforeAll(t provider.T) { } func (s *CartHandlerSuite) AfterAll(t provider.T) { - _ = s.psContainer.Terminate(context.Background()) s.server.Close() + s.lomsSrv.Stop() + s.lomsConn.Close() + + _ = s.psContainer.Terminate(context.Background()) } // DELETE /user//cart/ diff --git a/docker-compose.yaml b/docker-compose.yaml index 94bdcb4..539a8da 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,8 +1,8 @@ -version: "3.7" - services: cart: - build: cart/ + build: + context: . + dockerfile: cart/Dockerfile ports: - "8080:8080" depends_on: @@ -12,3 +12,12 @@ services: image: gitlab-registry.ozon.dev/go/classroom-18/students/homework-draft/products:latest ports: - "8082:8082" + + loms: + build: + context: . + dockerfile: loms/Dockerfile + ports: + - "8083:8083" + - "8084:8084" + - "8085:8085" diff --git a/docs/README.md b/docs/README.md index 714fe20..4ab939b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,3 +16,4 @@ 1. [Основы Go](./homework-1) 2. [Тестирование в Go](./homework-2) +3. [Межсервисное взаимодействие и основы эксплуатации](./homework-3) diff --git a/docs/homework-3/README.md b/docs/homework-3/README.md new file mode 100644 index 0000000..629211f --- /dev/null +++ b/docs/homework-3/README.md @@ -0,0 +1,262 @@ +# Домашнее задание по модулю "Межсервисное взаимодействие и основы эксплуатации" + +Добавить сервис LOMS и организовать взаимодействие между cart и loms с использованием gRPC. + +## Основное задание + +Необходимо: +- Имплементировать сервис, отвечающий за учет заказов и стоки по товарам. Логика работы методов и их контракты описаны ниже. +- Реализовать взаимодействие сервисов cart и loms через gRPC. + +Требование к решению: +- Создать protobuf контракт сервиса loms. +- В каждом проекте нужно добавить в Makefile команды для генерации .go файлов из proto файлов и установки нужных зависимостей (используем protoc). +- Состояние храним в in-memory, персистентное хранилище на данный момент не требуется. 2 репозитория - Stock и Order. +- Код должен быть покрыт тестами (тесты на методы репозитория - не требуются). +- Добавить gRPC интерцептор, который будет валидировать запросы через proto-gen-validator (правила валидации указываются в *.proto). +- Добавить HTTP-gateway. HTTP-запросы также должны проходить валидацию через добавленный выше gRPC интерцептор. + +## Дополнительное задание +- Добавить swagger-ui и возможность совершать запросы из swagger к сервису. +- Написать end-to-end тесты на все новые методы . + +## Спецификация LOMS (Logistics and Order Management System) + +Сервис отвечает за учет заказов и стоки по товарам. + +### OrderCreate + +Создает новый заказ для пользователя из списка переданных товаров с резервированием нужного количества стоков: ++ заказ получает статус "new" ++ резервирует нужное количество единиц товара ++ если удалось зарезервировать стоки, заказ получает статус "awaiting payment" ++ если не удалось зарезервировать стоки, заказ получает статус "failed", изменение стоков не происходит + +**Параметры ошибочных ответов:** + +| Сценарий | gRPC код ошибки (HTTP) | Описание | +|------------------------------------------------------------------------------|------------------------|---------------------------------------------------------------------------------| +| Вызов с нулевым или отрицательным значением userId | 3 (400) | Идентификатор пользователя должен быть натуральным числом (больше нуля) | +| Вызов c пустым списком товаров | 3 (400) | Идентификатор товара должен быть натуральным числом (больше нуля) | +| Вызов с нулевыми или отрицательными значениями sku в списке | 3 (400) | Количество должно быть натуральным числом (больше нуля) | +| Вызов с нулевыми или отрицательными значениями Count для любого sku в списке | 3 (400) | Count должен быть натуральным числом (больше нуля) | +| Превышение стоков хотя бы у одного товара | 9 (400) | Для всех товаров сток должен быть больше или равен запрашиваемому | +| Отсутствие информации по стокам в системе | 9 (400) | Невозможно создать заказ, если по хотя бы одному товару нет информации о стоках | +| Все остальные случаи | 13 или 2 (500) | Проблемы из-за неисправностей в системе | + +![loms-order-create](img/loms-order-create.png) + +Request +``` +{ + userId int64 + items []{ + sku int64 + count uint32 + } +} +``` + +Response +``` +{ + orderId int64 +} +``` + +### OrderInfo + +Показывает информацию по заказу. Товары в ответе должны быть отсортированы по SKU в порядке возрастания. + +**Параметры ошибочных ответов:** + +| Сценарий | gRPC код ошибки (HTTP) | Описание | +|-----------------------------------------------------|------------------------|---------------------------------------------------------------------| +| Вызов с нулевым или отрицательным значением orderId | 3 (400) | Идентификатор заказа должен быть натуральным числом (больше нуля) | +| Заказ с указанным orderId отсутствует в системе | 5 (404) | Можно получить информацию только для существующего в системе заказа | +| Все остальные случаи | 13 или 2 (500) | Проблемы из-за неисправностей в системе | + + +![loms-order-info](img/loms-order-info.png) + +Request +``` +{ + orderId int64 +} +``` + +Response +``` +{ + status string // (new | awaiting payment | failed | payed | cancelled) + userId int64 + items []{ + sku int64 + count uint32 + } +} +``` + +### OrderPay + +Помечает заказ оплаченным. Зарезервированные товары должны перейти в статус купленных. ++ удаляем зарезервированные стоки на товаре ++ заказ получает статус "payed" + +**Параметры ошибочных ответов:** + +| Сценарий | gRPC код ошибки (HTTP) | Описание | +|-----------------------------------------------------|------------------------|-------------------------------------------------------------------| +| Вызов с нулевым или отрицательным значением orderId | 3 (400) | Идентификатор заказа должен быть натуральным числом (больше нуля) | +| Оплата несуществующего заказа | 5 (404) | Можно оплачивать только существующий заказ | +| Оплата оплаченного заказа | 0 (200) | Оплата оплаченного заказа разрешается | +| Оплата заказа в статусе != "awaiting payment" | 9 (400) | Оплата заказа в невалидном статусе невозможна | +| Все остальные случаи | 13 или 2 (500) | Проблемы из-за неисправностей в системе | + +![loms-order-pay](img/loms-order-pay.png) + +Request +``` +{ + orderId int64 +} +``` + +Response +``` +{} +``` + +### OrderCancel + +Отменяет заказ, снимает резерв со всех товаров в заказе. ++ зарезервированные стоки на товаре становятся свободными стоками ++ заказ получает статус "cancelled" + +**Параметры ошибочных ответов:** + +| Сценарий | gRPC код ошибки (HTTP) | Описание | +|-----------------------------------------------------|------------------------|-------------------------------------------------------------------| +| Вызов с нулевым или отрицательным значением orderId | 3 (400) | Идентификатор заказа должен быть натуральным числом (больше нуля) | +| Отмена несуществующего заказа | 5 (404) | Можно отменять только существующий заказ | +| Отмена отмененного заказа | 0 (200) | Отмена отмененного заказа разрешается (идемпотентность) | +| Отмена заказа в статусе == "payed" или "failed" | 9 (400) | Невозможность отменить неудавшийся заказ, а также оплаченный | +| Все остальные случаи | 13 или 2 (500) | Проблемы из-за неисправностей в системе | + +![loms-order-cancel](img/loms-order-cancel.png) + +Request +``` +{ + orderId int64 +} +``` + +Response +``` +{} +``` + +### StocksInfo + +Возвращает количество товаров, которые можно купить. Если товар был зарезервирован у кого-то в заказе и ждет оплаты, его купить нельзя. +- данные по товарам берутся из stock-data.json (embed) +- структура stock: + - sku - товар + - total_count - всего товаров + - reserved - количество зарезервированных + +**Параметры ошибочных ответов:** + +| Сценарий | gRPC код ошибки (HTTP) | Описание | +|--------------------------------------------------|------------------------|--------------------------------------------------------------------| +| Вызов с нулевым или отрицательным значением sku | 3 (400) | Идентификатор товара должен быть натуральным числом (больше нуля) | +| Товара в запросе нет в базе стоков | 5 (404) | Можно получить информацию по стокам, если она есть в бд | +| Все остальные случаи | 13 или 2 (500) | Проблемы из-за неисправностей в системе | + +![loms-stok-info](img/loms-stok-info.png) + +Request +``` +{ + sku int64 +} +``` + +Response +``` +{ + count uint32 +} +``` + +## Доработки сервиса cart + +### POST /checkout/ + +Требуется добавить метод checkout - оформить заказ по всем товарам корзины. Вызывает loms.OrderCreate. +Сервис cart имеет HTTP-интерфейс. Взаимодействие с LOMS - через gRPC. + +**Параметры ошибочных ответов:** + +| Сценарий | HTTP код ошибки | Описание | +|-----------------------------------------------------|-----------------|-------------------------------------------------------------------------| +| Вызов с нулевым или отрицательным значением user_id | 400 | Идентификатор пользователя должен быть натуральным числом (больше нуля) | +| Вызов для пустой корзины | 404 | Невозможно оформить заказ для пустой корзины | +| Все остальные случаи | 500 | Проблемы из-за неисправностей в системе | + +![cart-cart-checkout](img/cart-cart-checkout.png) + +Request +``` +POST /checkout/ (user_id - int64) +``` + +Response +``` +{ + order_id int64 +} +``` + +### POST /user//cart/ + +Требуется добавить запрос в метод добавления товаров в корзину на проверку наличия стоков с помощью вызова gRPC метода loms.StocksInfo. + +**Параметры ошибочных ответов:** +Сценарии из прошлых домашних заданий без изменений. + +| Сценарий | HTTP код ошибки | Описание | +|-----------------------------------------|-----------------|--------------------------------------------------------------------| +| Превышение стоков при добавлении товара | 412 | Невозможно добавить товара по количеству больше, чем есть в стоках | +| Все остальные случаи | 500 | Проблемы из-за неисправностей в системе | + +![cart-cart-item-add](img/cart-cart-item-add.png) + +# Путь покупки товаров: + +- /user/{user_id}/cart/{sku_id} - Добавляем товар в корзину с проверкой на наличие стоков. +- /user/{user_id}/cart || /user/{user_id}/cart/{sku_id} - Можем удалять товары из корзины. +- /user/{user_id}/cart - Можем получить состав корзины. +- /checkout/{user_id} - Создаем заказ по товарам из корзины. +- /order/pay with body { "orderId": {order_id} } - Оплачиваем заказ. +- /order/cancel with body { "orderId": {order_id} } - Можем отменить заказ до оплаты. + +### Примечания +* e2e тесты проверяют HTTP коды ошибок, однако gRPC коды должны быть те, что указаны в требованиях. Например, могут быть проблемы с codes.FailedPrecondition, подробнее [тут](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go). +* Запросы из cart.http, loms.http & loms.grpc основаны на данных, что лежат в stock-data.json + +## Автоматические проверки + +Ваше решение должно проходить автоматические проверки: + +- Компиляция +- Линтер +- Unit-тесты (если есть) +- Автотесты + +Прохождение автоматических проверок влияет на итоговую оценку за домашнюю работу. + +### Дедлайны сдачи и проверки задания: +- 7 июня 23:59 (сдача) / 10 июня, 23:59 (проверка) diff --git a/docs/homework-3/cart.http b/docs/homework-3/cart.http new file mode 100644 index 0000000..cb39272 --- /dev/null +++ b/docs/homework-3/cart.http @@ -0,0 +1,69 @@ +### check cart state, expect empty cart +GET http://localhost:8080/user/31337/cart +Content-Type: application/json + +### expected: 404 (Not Found) {} + + +### add item to cart, see available stocks in loms db +POST http://localhost:8080/user/31337/cart/1076963 +Content-Type: application/json + +{ + "count": 1 +} +### expected: 200 (OK) {} + + +### check cart state, expect single sku in cart +GET http://localhost:8080/user/31337/cart + +### expected: 200 (OK) {"items":[{"sku":1076963,"count":1,"name":"Теория нравственных чувств | Смит Адам","price":3379}],"totalPrice":3379} + + +######################### +### checkout cart +POST http://localhost:8080/checkout/31337 +Content-Type: application/json + +### expected: 200 (OK) {"order_id":1} + + +### check orderID in LOMS +GET http://localhost:8084/order/info?orderId=1 +Content-Type: application/json +### expected: 200 (OK) {"status":"awaiting payment","user":31337,"Items":[{"sku":1076963,"count":1}]} + + +### check cart, expect empty +GET http://localhost:8080/user/31337/cart +Content-Type: application/json + +### expected: 404 (Not Found) {} + + +### add unknown item, expect error +POST http://localhost:8080/user/31337/cart/404 +Content-Type: application/json + +{ + "count": 1 +} +### expected: 412 (Precondition Failed) {} + + +### add item out of stock, expect error +POST http://localhost:8080/user/31337/cart/135937324 +Content-Type: application/json + +{ + "count": 65534 +} +### expected: 412 (Precondition Failed) {} + + +### checkout empty cart, expect error +POST http://localhost:8080/checkout/31337 +Content-Type: application/json + +### expected: 404 (Not Found) {} diff --git a/docs/homework-3/img/cart-cart-checkout.plantuml b/docs/homework-3/img/cart-cart-checkout.plantuml new file mode 100644 index 0000000..b803058 --- /dev/null +++ b/docs/homework-3/img/cart-cart-checkout.plantuml @@ -0,0 +1,18 @@ +@startuml + +actor User as u +collections Cart as c +database CartStorage as cs +collections Order as o + +u -> c : POST /checkout/ +activate c +c -> cs : cart.GetItemsByUserID +c -> o : gRPC Loms.OrderCreate\n\t- user\n\t- []item +c -> cs : cart.DeleteItemsByUserID + +c -> u : Response: 200 OK + +deactivate c + +@enduml diff --git a/docs/homework-3/img/cart-cart-checkout.png b/docs/homework-3/img/cart-cart-checkout.png new file mode 100644 index 0000000..9ed45bb Binary files /dev/null and b/docs/homework-3/img/cart-cart-checkout.png differ diff --git a/docs/homework-3/img/cart-cart-item-add.plantuml b/docs/homework-3/img/cart-cart-item-add.plantuml new file mode 100644 index 0000000..03537c7 --- /dev/null +++ b/docs/homework-3/img/cart-cart-item-add.plantuml @@ -0,0 +1,32 @@ +@startuml + +actor User as u +collections Cart as c +database CartStorage as cs +collections ProductService as p +collections Order as o + +u -> c : POST /user//cart/\n\t- count +activate c +loop for each item in request + c -> p : /get_product\n\t- sku\n\t- token + activate p + p -> c : \nResponse:\n\t- name\n\t- price + deactivate p + c -> c : validate product exists + + c -> o : gRPC Loms.StocksInfo\n\t- sku + activate o + o -> c : Response:\n\t- count + deactivate o + c -> c : validate stocks + alt stocks enough + c -> cs : cart.AddItem() + c -> u : 200 OK + else + c -> u : 412 Failed Precondition (insufficient stocks) + end +end +deactivate c + +@enduml diff --git a/docs/homework-3/img/cart-cart-item-add.png b/docs/homework-3/img/cart-cart-item-add.png new file mode 100644 index 0000000..1127d90 Binary files /dev/null and b/docs/homework-3/img/cart-cart-item-add.png differ diff --git a/docs/homework-3/img/loms-order-cancel.plantuml b/docs/homework-3/img/loms-order-cancel.plantuml new file mode 100644 index 0000000..5df2c4f --- /dev/null +++ b/docs/homework-3/img/loms-order-cancel.plantuml @@ -0,0 +1,18 @@ +@startuml + +actor User as u +collections LOMS as l +database OrdersStorage as os +database StocksStorage as ss + +u -> l : gRPC Loms.OrderCancel\n\t- orderID +activate l + +l -> os : order.GetByOrderID() +l -> ss : stocks.ReserveCancel() +l -> os : order.SetStatus(cancelled) +deactivate l + +l -> u : Response: OK (code_id=0) + +@enduml diff --git a/docs/homework-3/img/loms-order-cancel.png b/docs/homework-3/img/loms-order-cancel.png new file mode 100644 index 0000000..02a63f3 Binary files /dev/null and b/docs/homework-3/img/loms-order-cancel.png differ diff --git a/docs/homework-3/img/loms-order-create.plantuml b/docs/homework-3/img/loms-order-create.plantuml new file mode 100644 index 0000000..84a0aaa --- /dev/null +++ b/docs/homework-3/img/loms-order-create.plantuml @@ -0,0 +1,22 @@ +@startuml + +actor User as u +collections LOMS as l +database OrdersStorage as os +database StocksStorage as ss + +u -> l : gRPC Loms.OrderCreate\n\t- user\n\t- items: []item{\n\t\t- sku\n\t\t- count\n\t } +activate l +l -> os : order.Create()\n\tstatus=new +l -> ss : stocks.Reserve() + +alt Reserve success + l -> os : order.SetStatus(awaiting payment) + l -> u : Response: OK (code_id=0)\n\t- orderID +else + l -> os : order.SetStatus(failed) + l -> u : Failed Precondition (code_id 9) +end +deactivate l + +@enduml diff --git a/docs/homework-3/img/loms-order-create.png b/docs/homework-3/img/loms-order-create.png new file mode 100644 index 0000000..f25f876 Binary files /dev/null and b/docs/homework-3/img/loms-order-create.png differ diff --git a/docs/homework-3/img/loms-order-info.plantuml b/docs/homework-3/img/loms-order-info.plantuml new file mode 100644 index 0000000..ec875d8 --- /dev/null +++ b/docs/homework-3/img/loms-order-info.plantuml @@ -0,0 +1,19 @@ +@startuml + +actor User as u +collections LOMS as l +database OrdersStorage as os + +u -> l : gRPC Loms.OrderInfo\n\t- orderID int64 +activate l + +l -> os : order.GetByID() +alt order exists + l -> u : Response: OK (code_id=0)\n\t- status\n\t- user\n\t- []items{} +else + l -> u : Response: Not Found (code_id=5) +end + +deactivate l + +@enduml diff --git a/docs/homework-3/img/loms-order-info.png b/docs/homework-3/img/loms-order-info.png new file mode 100644 index 0000000..67250e9 Binary files /dev/null and b/docs/homework-3/img/loms-order-info.png differ diff --git a/docs/homework-3/img/loms-order-pay.plantuml b/docs/homework-3/img/loms-order-pay.plantuml new file mode 100644 index 0000000..8bb59db --- /dev/null +++ b/docs/homework-3/img/loms-order-pay.plantuml @@ -0,0 +1,17 @@ +@startuml + +actor User as u +collections LOMS as l +database OrdersStorage as os +database StocksStorage as ss + +u -> l : gRPC Loms.OrderPay\n\t- orderID +activate l +l -> ss : stocks.ReserveRemove() +l -> os : order.SetStatus(payed) + +l -> u : Response: OK (code_id=0) + +deactivate l + +@enduml diff --git a/docs/homework-3/img/loms-order-pay.png b/docs/homework-3/img/loms-order-pay.png new file mode 100644 index 0000000..d30bda2 Binary files /dev/null and b/docs/homework-3/img/loms-order-pay.png differ diff --git a/docs/homework-3/img/loms-stok-info.plantuml b/docs/homework-3/img/loms-stok-info.plantuml new file mode 100644 index 0000000..02edbbe --- /dev/null +++ b/docs/homework-3/img/loms-stok-info.plantuml @@ -0,0 +1,15 @@ +@startuml + +actor User as u +collections LOMS as l +database StocksStorage as ss + +u -> l : gRPC Loms.StocksInfo\n\t- sku +activate l + +l -> ss : stocks.GetBySKU() + +l -> u : Response: OK (code_id=0)\n- count +deactivate l + +@enduml diff --git a/docs/homework-3/img/loms-stok-info.png b/docs/homework-3/img/loms-stok-info.png new file mode 100644 index 0000000..6764b89 Binary files /dev/null and b/docs/homework-3/img/loms-stok-info.png differ diff --git a/docs/homework-3/loms.grpc b/docs/homework-3/loms.grpc new file mode 100644 index 0000000..97672ca --- /dev/null +++ b/docs/homework-3/loms.grpc @@ -0,0 +1,189 @@ +### create normal order +grpcurl -plaintext -d @ localhost:8083 loms.Loms.OrderCreate < 0 { + mmOrderCreate.mock.t.Fatalf("Some expectations are already set for the OrderRepository.OrderCreate method") + } + + mmOrderCreate.mock.funcOrderCreate = f + mmOrderCreate.mock.funcOrderCreateOrigin = minimock.CallerInfo(1) + return mmOrderCreate.mock +} + +// When sets expectation for the OrderRepository.OrderCreate which will trigger the result defined by the following +// Then helper +func (mmOrderCreate *mOrderRepositoryMockOrderCreate) When(ctx context.Context, order *entity.Order) *OrderRepositoryMockOrderCreateExpectation { + if mmOrderCreate.mock.funcOrderCreate != nil { + mmOrderCreate.mock.t.Fatalf("OrderRepositoryMock.OrderCreate mock is already set by Set") + } + + expectation := &OrderRepositoryMockOrderCreateExpectation{ + mock: mmOrderCreate.mock, + params: &OrderRepositoryMockOrderCreateParams{ctx, order}, + expectationOrigins: OrderRepositoryMockOrderCreateExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmOrderCreate.expectations = append(mmOrderCreate.expectations, expectation) + return expectation +} + +// Then sets up OrderRepository.OrderCreate return parameters for the expectation previously defined by the When method +func (e *OrderRepositoryMockOrderCreateExpectation) Then(i1 entity.ID, err error) *OrderRepositoryMock { + e.results = &OrderRepositoryMockOrderCreateResults{i1, err} + return e.mock +} + +// Times sets number of times OrderRepository.OrderCreate should be invoked +func (mmOrderCreate *mOrderRepositoryMockOrderCreate) Times(n uint64) *mOrderRepositoryMockOrderCreate { + if n == 0 { + mmOrderCreate.mock.t.Fatalf("Times of OrderRepositoryMock.OrderCreate mock can not be zero") + } + mm_atomic.StoreUint64(&mmOrderCreate.expectedInvocations, n) + mmOrderCreate.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmOrderCreate +} + +func (mmOrderCreate *mOrderRepositoryMockOrderCreate) invocationsDone() bool { + if len(mmOrderCreate.expectations) == 0 && mmOrderCreate.defaultExpectation == nil && mmOrderCreate.mock.funcOrderCreate == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmOrderCreate.mock.afterOrderCreateCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmOrderCreate.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// OrderCreate implements mm_service.OrderRepository +func (mmOrderCreate *OrderRepositoryMock) OrderCreate(ctx context.Context, order *entity.Order) (i1 entity.ID, err error) { + mm_atomic.AddUint64(&mmOrderCreate.beforeOrderCreateCounter, 1) + defer mm_atomic.AddUint64(&mmOrderCreate.afterOrderCreateCounter, 1) + + mmOrderCreate.t.Helper() + + if mmOrderCreate.inspectFuncOrderCreate != nil { + mmOrderCreate.inspectFuncOrderCreate(ctx, order) + } + + mm_params := OrderRepositoryMockOrderCreateParams{ctx, order} + + // Record call args + mmOrderCreate.OrderCreateMock.mutex.Lock() + mmOrderCreate.OrderCreateMock.callArgs = append(mmOrderCreate.OrderCreateMock.callArgs, &mm_params) + mmOrderCreate.OrderCreateMock.mutex.Unlock() + + for _, e := range mmOrderCreate.OrderCreateMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.i1, e.results.err + } + } + + if mmOrderCreate.OrderCreateMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmOrderCreate.OrderCreateMock.defaultExpectation.Counter, 1) + mm_want := mmOrderCreate.OrderCreateMock.defaultExpectation.params + mm_want_ptrs := mmOrderCreate.OrderCreateMock.defaultExpectation.paramPtrs + + mm_got := OrderRepositoryMockOrderCreateParams{ctx, order} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmOrderCreate.t.Errorf("OrderRepositoryMock.OrderCreate got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderCreate.OrderCreateMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.order != nil && !minimock.Equal(*mm_want_ptrs.order, mm_got.order) { + mmOrderCreate.t.Errorf("OrderRepositoryMock.OrderCreate got unexpected parameter order, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderCreate.OrderCreateMock.defaultExpectation.expectationOrigins.originOrder, *mm_want_ptrs.order, mm_got.order, minimock.Diff(*mm_want_ptrs.order, mm_got.order)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmOrderCreate.t.Errorf("OrderRepositoryMock.OrderCreate got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderCreate.OrderCreateMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmOrderCreate.OrderCreateMock.defaultExpectation.results + if mm_results == nil { + mmOrderCreate.t.Fatal("No results are set for the OrderRepositoryMock.OrderCreate") + } + return (*mm_results).i1, (*mm_results).err + } + if mmOrderCreate.funcOrderCreate != nil { + return mmOrderCreate.funcOrderCreate(ctx, order) + } + mmOrderCreate.t.Fatalf("Unexpected call to OrderRepositoryMock.OrderCreate. %v %v", ctx, order) + return +} + +// OrderCreateAfterCounter returns a count of finished OrderRepositoryMock.OrderCreate invocations +func (mmOrderCreate *OrderRepositoryMock) OrderCreateAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmOrderCreate.afterOrderCreateCounter) +} + +// OrderCreateBeforeCounter returns a count of OrderRepositoryMock.OrderCreate invocations +func (mmOrderCreate *OrderRepositoryMock) OrderCreateBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmOrderCreate.beforeOrderCreateCounter) +} + +// Calls returns a list of arguments used in each call to OrderRepositoryMock.OrderCreate. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmOrderCreate *mOrderRepositoryMockOrderCreate) Calls() []*OrderRepositoryMockOrderCreateParams { + mmOrderCreate.mutex.RLock() + + argCopy := make([]*OrderRepositoryMockOrderCreateParams, len(mmOrderCreate.callArgs)) + copy(argCopy, mmOrderCreate.callArgs) + + mmOrderCreate.mutex.RUnlock() + + return argCopy +} + +// MinimockOrderCreateDone returns true if the count of the OrderCreate invocations corresponds +// the number of defined expectations +func (m *OrderRepositoryMock) MinimockOrderCreateDone() bool { + if m.OrderCreateMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.OrderCreateMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.OrderCreateMock.invocationsDone() +} + +// MinimockOrderCreateInspect logs each unmet expectation +func (m *OrderRepositoryMock) MinimockOrderCreateInspect() { + for _, e := range m.OrderCreateMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderCreate at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterOrderCreateCounter := mm_atomic.LoadUint64(&m.afterOrderCreateCounter) + // if default expectation was set then invocations count should be greater than zero + if m.OrderCreateMock.defaultExpectation != nil && afterOrderCreateCounter < 1 { + if m.OrderCreateMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderCreate at\n%s", m.OrderCreateMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderCreate at\n%s with params: %#v", m.OrderCreateMock.defaultExpectation.expectationOrigins.origin, *m.OrderCreateMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcOrderCreate != nil && afterOrderCreateCounter < 1 { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderCreate at\n%s", m.funcOrderCreateOrigin) + } + + if !m.OrderCreateMock.invocationsDone() && afterOrderCreateCounter > 0 { + m.t.Errorf("Expected %d calls to OrderRepositoryMock.OrderCreate at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.OrderCreateMock.expectedInvocations), m.OrderCreateMock.expectedInvocationsOrigin, afterOrderCreateCounter) + } +} + +type mOrderRepositoryMockOrderGetByID struct { + optional bool + mock *OrderRepositoryMock + defaultExpectation *OrderRepositoryMockOrderGetByIDExpectation + expectations []*OrderRepositoryMockOrderGetByIDExpectation + + callArgs []*OrderRepositoryMockOrderGetByIDParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// OrderRepositoryMockOrderGetByIDExpectation specifies expectation struct of the OrderRepository.OrderGetByID +type OrderRepositoryMockOrderGetByIDExpectation struct { + mock *OrderRepositoryMock + params *OrderRepositoryMockOrderGetByIDParams + paramPtrs *OrderRepositoryMockOrderGetByIDParamPtrs + expectationOrigins OrderRepositoryMockOrderGetByIDExpectationOrigins + results *OrderRepositoryMockOrderGetByIDResults + returnOrigin string + Counter uint64 +} + +// OrderRepositoryMockOrderGetByIDParams contains parameters of the OrderRepository.OrderGetByID +type OrderRepositoryMockOrderGetByIDParams struct { + ctx context.Context + orderID entity.ID +} + +// OrderRepositoryMockOrderGetByIDParamPtrs contains pointers to parameters of the OrderRepository.OrderGetByID +type OrderRepositoryMockOrderGetByIDParamPtrs struct { + ctx *context.Context + orderID *entity.ID +} + +// OrderRepositoryMockOrderGetByIDResults contains results of the OrderRepository.OrderGetByID +type OrderRepositoryMockOrderGetByIDResults struct { + op1 *entity.Order + err error +} + +// OrderRepositoryMockOrderGetByIDOrigins contains origins of expectations of the OrderRepository.OrderGetByID +type OrderRepositoryMockOrderGetByIDExpectationOrigins struct { + origin string + originCtx string + originOrderID string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Optional() *mOrderRepositoryMockOrderGetByID { + mmOrderGetByID.optional = true + return mmOrderGetByID +} + +// Expect sets up expected params for OrderRepository.OrderGetByID +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Expect(ctx context.Context, orderID entity.ID) *mOrderRepositoryMockOrderGetByID { + if mmOrderGetByID.mock.funcOrderGetByID != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Set") + } + + if mmOrderGetByID.defaultExpectation == nil { + mmOrderGetByID.defaultExpectation = &OrderRepositoryMockOrderGetByIDExpectation{} + } + + if mmOrderGetByID.defaultExpectation.paramPtrs != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by ExpectParams functions") + } + + mmOrderGetByID.defaultExpectation.params = &OrderRepositoryMockOrderGetByIDParams{ctx, orderID} + mmOrderGetByID.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmOrderGetByID.expectations { + if minimock.Equal(e.params, mmOrderGetByID.defaultExpectation.params) { + mmOrderGetByID.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmOrderGetByID.defaultExpectation.params) + } + } + + return mmOrderGetByID +} + +// ExpectCtxParam1 sets up expected param ctx for OrderRepository.OrderGetByID +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) ExpectCtxParam1(ctx context.Context) *mOrderRepositoryMockOrderGetByID { + if mmOrderGetByID.mock.funcOrderGetByID != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Set") + } + + if mmOrderGetByID.defaultExpectation == nil { + mmOrderGetByID.defaultExpectation = &OrderRepositoryMockOrderGetByIDExpectation{} + } + + if mmOrderGetByID.defaultExpectation.params != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Expect") + } + + if mmOrderGetByID.defaultExpectation.paramPtrs == nil { + mmOrderGetByID.defaultExpectation.paramPtrs = &OrderRepositoryMockOrderGetByIDParamPtrs{} + } + mmOrderGetByID.defaultExpectation.paramPtrs.ctx = &ctx + mmOrderGetByID.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmOrderGetByID +} + +// ExpectOrderIDParam2 sets up expected param orderID for OrderRepository.OrderGetByID +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) ExpectOrderIDParam2(orderID entity.ID) *mOrderRepositoryMockOrderGetByID { + if mmOrderGetByID.mock.funcOrderGetByID != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Set") + } + + if mmOrderGetByID.defaultExpectation == nil { + mmOrderGetByID.defaultExpectation = &OrderRepositoryMockOrderGetByIDExpectation{} + } + + if mmOrderGetByID.defaultExpectation.params != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Expect") + } + + if mmOrderGetByID.defaultExpectation.paramPtrs == nil { + mmOrderGetByID.defaultExpectation.paramPtrs = &OrderRepositoryMockOrderGetByIDParamPtrs{} + } + mmOrderGetByID.defaultExpectation.paramPtrs.orderID = &orderID + mmOrderGetByID.defaultExpectation.expectationOrigins.originOrderID = minimock.CallerInfo(1) + + return mmOrderGetByID +} + +// Inspect accepts an inspector function that has same arguments as the OrderRepository.OrderGetByID +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Inspect(f func(ctx context.Context, orderID entity.ID)) *mOrderRepositoryMockOrderGetByID { + if mmOrderGetByID.mock.inspectFuncOrderGetByID != nil { + mmOrderGetByID.mock.t.Fatalf("Inspect function is already set for OrderRepositoryMock.OrderGetByID") + } + + mmOrderGetByID.mock.inspectFuncOrderGetByID = f + + return mmOrderGetByID +} + +// Return sets up results that will be returned by OrderRepository.OrderGetByID +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Return(op1 *entity.Order, err error) *OrderRepositoryMock { + if mmOrderGetByID.mock.funcOrderGetByID != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Set") + } + + if mmOrderGetByID.defaultExpectation == nil { + mmOrderGetByID.defaultExpectation = &OrderRepositoryMockOrderGetByIDExpectation{mock: mmOrderGetByID.mock} + } + mmOrderGetByID.defaultExpectation.results = &OrderRepositoryMockOrderGetByIDResults{op1, err} + mmOrderGetByID.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmOrderGetByID.mock +} + +// Set uses given function f to mock the OrderRepository.OrderGetByID method +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Set(f func(ctx context.Context, orderID entity.ID) (op1 *entity.Order, err error)) *OrderRepositoryMock { + if mmOrderGetByID.defaultExpectation != nil { + mmOrderGetByID.mock.t.Fatalf("Default expectation is already set for the OrderRepository.OrderGetByID method") + } + + if len(mmOrderGetByID.expectations) > 0 { + mmOrderGetByID.mock.t.Fatalf("Some expectations are already set for the OrderRepository.OrderGetByID method") + } + + mmOrderGetByID.mock.funcOrderGetByID = f + mmOrderGetByID.mock.funcOrderGetByIDOrigin = minimock.CallerInfo(1) + return mmOrderGetByID.mock +} + +// When sets expectation for the OrderRepository.OrderGetByID which will trigger the result defined by the following +// Then helper +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) When(ctx context.Context, orderID entity.ID) *OrderRepositoryMockOrderGetByIDExpectation { + if mmOrderGetByID.mock.funcOrderGetByID != nil { + mmOrderGetByID.mock.t.Fatalf("OrderRepositoryMock.OrderGetByID mock is already set by Set") + } + + expectation := &OrderRepositoryMockOrderGetByIDExpectation{ + mock: mmOrderGetByID.mock, + params: &OrderRepositoryMockOrderGetByIDParams{ctx, orderID}, + expectationOrigins: OrderRepositoryMockOrderGetByIDExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmOrderGetByID.expectations = append(mmOrderGetByID.expectations, expectation) + return expectation +} + +// Then sets up OrderRepository.OrderGetByID return parameters for the expectation previously defined by the When method +func (e *OrderRepositoryMockOrderGetByIDExpectation) Then(op1 *entity.Order, err error) *OrderRepositoryMock { + e.results = &OrderRepositoryMockOrderGetByIDResults{op1, err} + return e.mock +} + +// Times sets number of times OrderRepository.OrderGetByID should be invoked +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Times(n uint64) *mOrderRepositoryMockOrderGetByID { + if n == 0 { + mmOrderGetByID.mock.t.Fatalf("Times of OrderRepositoryMock.OrderGetByID mock can not be zero") + } + mm_atomic.StoreUint64(&mmOrderGetByID.expectedInvocations, n) + mmOrderGetByID.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmOrderGetByID +} + +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) invocationsDone() bool { + if len(mmOrderGetByID.expectations) == 0 && mmOrderGetByID.defaultExpectation == nil && mmOrderGetByID.mock.funcOrderGetByID == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmOrderGetByID.mock.afterOrderGetByIDCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmOrderGetByID.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// OrderGetByID implements mm_service.OrderRepository +func (mmOrderGetByID *OrderRepositoryMock) OrderGetByID(ctx context.Context, orderID entity.ID) (op1 *entity.Order, err error) { + mm_atomic.AddUint64(&mmOrderGetByID.beforeOrderGetByIDCounter, 1) + defer mm_atomic.AddUint64(&mmOrderGetByID.afterOrderGetByIDCounter, 1) + + mmOrderGetByID.t.Helper() + + if mmOrderGetByID.inspectFuncOrderGetByID != nil { + mmOrderGetByID.inspectFuncOrderGetByID(ctx, orderID) + } + + mm_params := OrderRepositoryMockOrderGetByIDParams{ctx, orderID} + + // Record call args + mmOrderGetByID.OrderGetByIDMock.mutex.Lock() + mmOrderGetByID.OrderGetByIDMock.callArgs = append(mmOrderGetByID.OrderGetByIDMock.callArgs, &mm_params) + mmOrderGetByID.OrderGetByIDMock.mutex.Unlock() + + for _, e := range mmOrderGetByID.OrderGetByIDMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.op1, e.results.err + } + } + + if mmOrderGetByID.OrderGetByIDMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmOrderGetByID.OrderGetByIDMock.defaultExpectation.Counter, 1) + mm_want := mmOrderGetByID.OrderGetByIDMock.defaultExpectation.params + mm_want_ptrs := mmOrderGetByID.OrderGetByIDMock.defaultExpectation.paramPtrs + + mm_got := OrderRepositoryMockOrderGetByIDParams{ctx, orderID} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmOrderGetByID.t.Errorf("OrderRepositoryMock.OrderGetByID got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderGetByID.OrderGetByIDMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.orderID != nil && !minimock.Equal(*mm_want_ptrs.orderID, mm_got.orderID) { + mmOrderGetByID.t.Errorf("OrderRepositoryMock.OrderGetByID got unexpected parameter orderID, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderGetByID.OrderGetByIDMock.defaultExpectation.expectationOrigins.originOrderID, *mm_want_ptrs.orderID, mm_got.orderID, minimock.Diff(*mm_want_ptrs.orderID, mm_got.orderID)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmOrderGetByID.t.Errorf("OrderRepositoryMock.OrderGetByID got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderGetByID.OrderGetByIDMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmOrderGetByID.OrderGetByIDMock.defaultExpectation.results + if mm_results == nil { + mmOrderGetByID.t.Fatal("No results are set for the OrderRepositoryMock.OrderGetByID") + } + return (*mm_results).op1, (*mm_results).err + } + if mmOrderGetByID.funcOrderGetByID != nil { + return mmOrderGetByID.funcOrderGetByID(ctx, orderID) + } + mmOrderGetByID.t.Fatalf("Unexpected call to OrderRepositoryMock.OrderGetByID. %v %v", ctx, orderID) + return +} + +// OrderGetByIDAfterCounter returns a count of finished OrderRepositoryMock.OrderGetByID invocations +func (mmOrderGetByID *OrderRepositoryMock) OrderGetByIDAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmOrderGetByID.afterOrderGetByIDCounter) +} + +// OrderGetByIDBeforeCounter returns a count of OrderRepositoryMock.OrderGetByID invocations +func (mmOrderGetByID *OrderRepositoryMock) OrderGetByIDBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmOrderGetByID.beforeOrderGetByIDCounter) +} + +// Calls returns a list of arguments used in each call to OrderRepositoryMock.OrderGetByID. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmOrderGetByID *mOrderRepositoryMockOrderGetByID) Calls() []*OrderRepositoryMockOrderGetByIDParams { + mmOrderGetByID.mutex.RLock() + + argCopy := make([]*OrderRepositoryMockOrderGetByIDParams, len(mmOrderGetByID.callArgs)) + copy(argCopy, mmOrderGetByID.callArgs) + + mmOrderGetByID.mutex.RUnlock() + + return argCopy +} + +// MinimockOrderGetByIDDone returns true if the count of the OrderGetByID invocations corresponds +// the number of defined expectations +func (m *OrderRepositoryMock) MinimockOrderGetByIDDone() bool { + if m.OrderGetByIDMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.OrderGetByIDMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.OrderGetByIDMock.invocationsDone() +} + +// MinimockOrderGetByIDInspect logs each unmet expectation +func (m *OrderRepositoryMock) MinimockOrderGetByIDInspect() { + for _, e := range m.OrderGetByIDMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderGetByID at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterOrderGetByIDCounter := mm_atomic.LoadUint64(&m.afterOrderGetByIDCounter) + // if default expectation was set then invocations count should be greater than zero + if m.OrderGetByIDMock.defaultExpectation != nil && afterOrderGetByIDCounter < 1 { + if m.OrderGetByIDMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderGetByID at\n%s", m.OrderGetByIDMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderGetByID at\n%s with params: %#v", m.OrderGetByIDMock.defaultExpectation.expectationOrigins.origin, *m.OrderGetByIDMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcOrderGetByID != nil && afterOrderGetByIDCounter < 1 { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderGetByID at\n%s", m.funcOrderGetByIDOrigin) + } + + if !m.OrderGetByIDMock.invocationsDone() && afterOrderGetByIDCounter > 0 { + m.t.Errorf("Expected %d calls to OrderRepositoryMock.OrderGetByID at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.OrderGetByIDMock.expectedInvocations), m.OrderGetByIDMock.expectedInvocationsOrigin, afterOrderGetByIDCounter) + } +} + +type mOrderRepositoryMockOrderSetStatus struct { + optional bool + mock *OrderRepositoryMock + defaultExpectation *OrderRepositoryMockOrderSetStatusExpectation + expectations []*OrderRepositoryMockOrderSetStatusExpectation + + callArgs []*OrderRepositoryMockOrderSetStatusParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// OrderRepositoryMockOrderSetStatusExpectation specifies expectation struct of the OrderRepository.OrderSetStatus +type OrderRepositoryMockOrderSetStatusExpectation struct { + mock *OrderRepositoryMock + params *OrderRepositoryMockOrderSetStatusParams + paramPtrs *OrderRepositoryMockOrderSetStatusParamPtrs + expectationOrigins OrderRepositoryMockOrderSetStatusExpectationOrigins + results *OrderRepositoryMockOrderSetStatusResults + returnOrigin string + Counter uint64 +} + +// OrderRepositoryMockOrderSetStatusParams contains parameters of the OrderRepository.OrderSetStatus +type OrderRepositoryMockOrderSetStatusParams struct { + ctx context.Context + orderID entity.ID + newStatus string +} + +// OrderRepositoryMockOrderSetStatusParamPtrs contains pointers to parameters of the OrderRepository.OrderSetStatus +type OrderRepositoryMockOrderSetStatusParamPtrs struct { + ctx *context.Context + orderID *entity.ID + newStatus *string +} + +// OrderRepositoryMockOrderSetStatusResults contains results of the OrderRepository.OrderSetStatus +type OrderRepositoryMockOrderSetStatusResults struct { + err error +} + +// OrderRepositoryMockOrderSetStatusOrigins contains origins of expectations of the OrderRepository.OrderSetStatus +type OrderRepositoryMockOrderSetStatusExpectationOrigins struct { + origin string + originCtx string + originOrderID string + originNewStatus string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Optional() *mOrderRepositoryMockOrderSetStatus { + mmOrderSetStatus.optional = true + return mmOrderSetStatus +} + +// Expect sets up expected params for OrderRepository.OrderSetStatus +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Expect(ctx context.Context, orderID entity.ID, newStatus string) *mOrderRepositoryMockOrderSetStatus { + if mmOrderSetStatus.mock.funcOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Set") + } + + if mmOrderSetStatus.defaultExpectation == nil { + mmOrderSetStatus.defaultExpectation = &OrderRepositoryMockOrderSetStatusExpectation{} + } + + if mmOrderSetStatus.defaultExpectation.paramPtrs != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by ExpectParams functions") + } + + mmOrderSetStatus.defaultExpectation.params = &OrderRepositoryMockOrderSetStatusParams{ctx, orderID, newStatus} + mmOrderSetStatus.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmOrderSetStatus.expectations { + if minimock.Equal(e.params, mmOrderSetStatus.defaultExpectation.params) { + mmOrderSetStatus.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmOrderSetStatus.defaultExpectation.params) + } + } + + return mmOrderSetStatus +} + +// ExpectCtxParam1 sets up expected param ctx for OrderRepository.OrderSetStatus +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) ExpectCtxParam1(ctx context.Context) *mOrderRepositoryMockOrderSetStatus { + if mmOrderSetStatus.mock.funcOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Set") + } + + if mmOrderSetStatus.defaultExpectation == nil { + mmOrderSetStatus.defaultExpectation = &OrderRepositoryMockOrderSetStatusExpectation{} + } + + if mmOrderSetStatus.defaultExpectation.params != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Expect") + } + + if mmOrderSetStatus.defaultExpectation.paramPtrs == nil { + mmOrderSetStatus.defaultExpectation.paramPtrs = &OrderRepositoryMockOrderSetStatusParamPtrs{} + } + mmOrderSetStatus.defaultExpectation.paramPtrs.ctx = &ctx + mmOrderSetStatus.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmOrderSetStatus +} + +// ExpectOrderIDParam2 sets up expected param orderID for OrderRepository.OrderSetStatus +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) ExpectOrderIDParam2(orderID entity.ID) *mOrderRepositoryMockOrderSetStatus { + if mmOrderSetStatus.mock.funcOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Set") + } + + if mmOrderSetStatus.defaultExpectation == nil { + mmOrderSetStatus.defaultExpectation = &OrderRepositoryMockOrderSetStatusExpectation{} + } + + if mmOrderSetStatus.defaultExpectation.params != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Expect") + } + + if mmOrderSetStatus.defaultExpectation.paramPtrs == nil { + mmOrderSetStatus.defaultExpectation.paramPtrs = &OrderRepositoryMockOrderSetStatusParamPtrs{} + } + mmOrderSetStatus.defaultExpectation.paramPtrs.orderID = &orderID + mmOrderSetStatus.defaultExpectation.expectationOrigins.originOrderID = minimock.CallerInfo(1) + + return mmOrderSetStatus +} + +// ExpectNewStatusParam3 sets up expected param newStatus for OrderRepository.OrderSetStatus +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) ExpectNewStatusParam3(newStatus string) *mOrderRepositoryMockOrderSetStatus { + if mmOrderSetStatus.mock.funcOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Set") + } + + if mmOrderSetStatus.defaultExpectation == nil { + mmOrderSetStatus.defaultExpectation = &OrderRepositoryMockOrderSetStatusExpectation{} + } + + if mmOrderSetStatus.defaultExpectation.params != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Expect") + } + + if mmOrderSetStatus.defaultExpectation.paramPtrs == nil { + mmOrderSetStatus.defaultExpectation.paramPtrs = &OrderRepositoryMockOrderSetStatusParamPtrs{} + } + mmOrderSetStatus.defaultExpectation.paramPtrs.newStatus = &newStatus + mmOrderSetStatus.defaultExpectation.expectationOrigins.originNewStatus = minimock.CallerInfo(1) + + return mmOrderSetStatus +} + +// Inspect accepts an inspector function that has same arguments as the OrderRepository.OrderSetStatus +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Inspect(f func(ctx context.Context, orderID entity.ID, newStatus string)) *mOrderRepositoryMockOrderSetStatus { + if mmOrderSetStatus.mock.inspectFuncOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("Inspect function is already set for OrderRepositoryMock.OrderSetStatus") + } + + mmOrderSetStatus.mock.inspectFuncOrderSetStatus = f + + return mmOrderSetStatus +} + +// Return sets up results that will be returned by OrderRepository.OrderSetStatus +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Return(err error) *OrderRepositoryMock { + if mmOrderSetStatus.mock.funcOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Set") + } + + if mmOrderSetStatus.defaultExpectation == nil { + mmOrderSetStatus.defaultExpectation = &OrderRepositoryMockOrderSetStatusExpectation{mock: mmOrderSetStatus.mock} + } + mmOrderSetStatus.defaultExpectation.results = &OrderRepositoryMockOrderSetStatusResults{err} + mmOrderSetStatus.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmOrderSetStatus.mock +} + +// Set uses given function f to mock the OrderRepository.OrderSetStatus method +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Set(f func(ctx context.Context, orderID entity.ID, newStatus string) (err error)) *OrderRepositoryMock { + if mmOrderSetStatus.defaultExpectation != nil { + mmOrderSetStatus.mock.t.Fatalf("Default expectation is already set for the OrderRepository.OrderSetStatus method") + } + + if len(mmOrderSetStatus.expectations) > 0 { + mmOrderSetStatus.mock.t.Fatalf("Some expectations are already set for the OrderRepository.OrderSetStatus method") + } + + mmOrderSetStatus.mock.funcOrderSetStatus = f + mmOrderSetStatus.mock.funcOrderSetStatusOrigin = minimock.CallerInfo(1) + return mmOrderSetStatus.mock +} + +// When sets expectation for the OrderRepository.OrderSetStatus which will trigger the result defined by the following +// Then helper +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) When(ctx context.Context, orderID entity.ID, newStatus string) *OrderRepositoryMockOrderSetStatusExpectation { + if mmOrderSetStatus.mock.funcOrderSetStatus != nil { + mmOrderSetStatus.mock.t.Fatalf("OrderRepositoryMock.OrderSetStatus mock is already set by Set") + } + + expectation := &OrderRepositoryMockOrderSetStatusExpectation{ + mock: mmOrderSetStatus.mock, + params: &OrderRepositoryMockOrderSetStatusParams{ctx, orderID, newStatus}, + expectationOrigins: OrderRepositoryMockOrderSetStatusExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmOrderSetStatus.expectations = append(mmOrderSetStatus.expectations, expectation) + return expectation +} + +// Then sets up OrderRepository.OrderSetStatus return parameters for the expectation previously defined by the When method +func (e *OrderRepositoryMockOrderSetStatusExpectation) Then(err error) *OrderRepositoryMock { + e.results = &OrderRepositoryMockOrderSetStatusResults{err} + return e.mock +} + +// Times sets number of times OrderRepository.OrderSetStatus should be invoked +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Times(n uint64) *mOrderRepositoryMockOrderSetStatus { + if n == 0 { + mmOrderSetStatus.mock.t.Fatalf("Times of OrderRepositoryMock.OrderSetStatus mock can not be zero") + } + mm_atomic.StoreUint64(&mmOrderSetStatus.expectedInvocations, n) + mmOrderSetStatus.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmOrderSetStatus +} + +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) invocationsDone() bool { + if len(mmOrderSetStatus.expectations) == 0 && mmOrderSetStatus.defaultExpectation == nil && mmOrderSetStatus.mock.funcOrderSetStatus == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmOrderSetStatus.mock.afterOrderSetStatusCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmOrderSetStatus.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// OrderSetStatus implements mm_service.OrderRepository +func (mmOrderSetStatus *OrderRepositoryMock) OrderSetStatus(ctx context.Context, orderID entity.ID, newStatus string) (err error) { + mm_atomic.AddUint64(&mmOrderSetStatus.beforeOrderSetStatusCounter, 1) + defer mm_atomic.AddUint64(&mmOrderSetStatus.afterOrderSetStatusCounter, 1) + + mmOrderSetStatus.t.Helper() + + if mmOrderSetStatus.inspectFuncOrderSetStatus != nil { + mmOrderSetStatus.inspectFuncOrderSetStatus(ctx, orderID, newStatus) + } + + mm_params := OrderRepositoryMockOrderSetStatusParams{ctx, orderID, newStatus} + + // Record call args + mmOrderSetStatus.OrderSetStatusMock.mutex.Lock() + mmOrderSetStatus.OrderSetStatusMock.callArgs = append(mmOrderSetStatus.OrderSetStatusMock.callArgs, &mm_params) + mmOrderSetStatus.OrderSetStatusMock.mutex.Unlock() + + for _, e := range mmOrderSetStatus.OrderSetStatusMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.err + } + } + + if mmOrderSetStatus.OrderSetStatusMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.Counter, 1) + mm_want := mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.params + mm_want_ptrs := mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.paramPtrs + + mm_got := OrderRepositoryMockOrderSetStatusParams{ctx, orderID, newStatus} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmOrderSetStatus.t.Errorf("OrderRepositoryMock.OrderSetStatus got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.orderID != nil && !minimock.Equal(*mm_want_ptrs.orderID, mm_got.orderID) { + mmOrderSetStatus.t.Errorf("OrderRepositoryMock.OrderSetStatus got unexpected parameter orderID, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.expectationOrigins.originOrderID, *mm_want_ptrs.orderID, mm_got.orderID, minimock.Diff(*mm_want_ptrs.orderID, mm_got.orderID)) + } + + if mm_want_ptrs.newStatus != nil && !minimock.Equal(*mm_want_ptrs.newStatus, mm_got.newStatus) { + mmOrderSetStatus.t.Errorf("OrderRepositoryMock.OrderSetStatus got unexpected parameter newStatus, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.expectationOrigins.originNewStatus, *mm_want_ptrs.newStatus, mm_got.newStatus, minimock.Diff(*mm_want_ptrs.newStatus, mm_got.newStatus)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmOrderSetStatus.t.Errorf("OrderRepositoryMock.OrderSetStatus got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmOrderSetStatus.OrderSetStatusMock.defaultExpectation.results + if mm_results == nil { + mmOrderSetStatus.t.Fatal("No results are set for the OrderRepositoryMock.OrderSetStatus") + } + return (*mm_results).err + } + if mmOrderSetStatus.funcOrderSetStatus != nil { + return mmOrderSetStatus.funcOrderSetStatus(ctx, orderID, newStatus) + } + mmOrderSetStatus.t.Fatalf("Unexpected call to OrderRepositoryMock.OrderSetStatus. %v %v %v", ctx, orderID, newStatus) + return +} + +// OrderSetStatusAfterCounter returns a count of finished OrderRepositoryMock.OrderSetStatus invocations +func (mmOrderSetStatus *OrderRepositoryMock) OrderSetStatusAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmOrderSetStatus.afterOrderSetStatusCounter) +} + +// OrderSetStatusBeforeCounter returns a count of OrderRepositoryMock.OrderSetStatus invocations +func (mmOrderSetStatus *OrderRepositoryMock) OrderSetStatusBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmOrderSetStatus.beforeOrderSetStatusCounter) +} + +// Calls returns a list of arguments used in each call to OrderRepositoryMock.OrderSetStatus. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmOrderSetStatus *mOrderRepositoryMockOrderSetStatus) Calls() []*OrderRepositoryMockOrderSetStatusParams { + mmOrderSetStatus.mutex.RLock() + + argCopy := make([]*OrderRepositoryMockOrderSetStatusParams, len(mmOrderSetStatus.callArgs)) + copy(argCopy, mmOrderSetStatus.callArgs) + + mmOrderSetStatus.mutex.RUnlock() + + return argCopy +} + +// MinimockOrderSetStatusDone returns true if the count of the OrderSetStatus invocations corresponds +// the number of defined expectations +func (m *OrderRepositoryMock) MinimockOrderSetStatusDone() bool { + if m.OrderSetStatusMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.OrderSetStatusMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.OrderSetStatusMock.invocationsDone() +} + +// MinimockOrderSetStatusInspect logs each unmet expectation +func (m *OrderRepositoryMock) MinimockOrderSetStatusInspect() { + for _, e := range m.OrderSetStatusMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderSetStatus at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterOrderSetStatusCounter := mm_atomic.LoadUint64(&m.afterOrderSetStatusCounter) + // if default expectation was set then invocations count should be greater than zero + if m.OrderSetStatusMock.defaultExpectation != nil && afterOrderSetStatusCounter < 1 { + if m.OrderSetStatusMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderSetStatus at\n%s", m.OrderSetStatusMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderSetStatus at\n%s with params: %#v", m.OrderSetStatusMock.defaultExpectation.expectationOrigins.origin, *m.OrderSetStatusMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcOrderSetStatus != nil && afterOrderSetStatusCounter < 1 { + m.t.Errorf("Expected call to OrderRepositoryMock.OrderSetStatus at\n%s", m.funcOrderSetStatusOrigin) + } + + if !m.OrderSetStatusMock.invocationsDone() && afterOrderSetStatusCounter > 0 { + m.t.Errorf("Expected %d calls to OrderRepositoryMock.OrderSetStatus at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.OrderSetStatusMock.expectedInvocations), m.OrderSetStatusMock.expectedInvocationsOrigin, afterOrderSetStatusCounter) + } +} + +// MinimockFinish checks that all mocked methods have been called the expected number of times +func (m *OrderRepositoryMock) MinimockFinish() { + m.finishOnce.Do(func() { + if !m.minimockDone() { + m.MinimockOrderCreateInspect() + + m.MinimockOrderGetByIDInspect() + + m.MinimockOrderSetStatusInspect() + } + }) +} + +// MinimockWait waits for all mocked methods to be called the expected number of times +func (m *OrderRepositoryMock) MinimockWait(timeout mm_time.Duration) { + timeoutCh := mm_time.After(timeout) + for { + if m.minimockDone() { + return + } + select { + case <-timeoutCh: + m.MinimockFinish() + return + case <-mm_time.After(10 * mm_time.Millisecond): + } + } +} + +func (m *OrderRepositoryMock) minimockDone() bool { + done := true + return done && + m.MinimockOrderCreateDone() && + m.MinimockOrderGetByIDDone() && + m.MinimockOrderSetStatusDone() +} diff --git a/loms/internal/domain/service/mock/stock_repository_mock.go b/loms/internal/domain/service/mock/stock_repository_mock.go new file mode 100644 index 0000000..62f73b4 --- /dev/null +++ b/loms/internal/domain/service/mock/stock_repository_mock.go @@ -0,0 +1,1483 @@ +// Code generated by http://github.com/gojuno/minimock (v3.4.5). DO NOT EDIT. + +package mock + +//go:generate minimock -i route256/loms/internal/domain/loms/service.StockRepository -o stock_repository_mock.go -n StockRepositoryMock -p mock + +import ( + "context" + "route256/loms/internal/domain/entity" + "sync" + mm_atomic "sync/atomic" + mm_time "time" + + "github.com/gojuno/minimock/v3" +) + +// StockRepositoryMock implements mm_service.StockRepository +type StockRepositoryMock struct { + t minimock.Tester + finishOnce sync.Once + + funcStockCancel func(ctx context.Context, stock *entity.Stock) (err error) + funcStockCancelOrigin string + inspectFuncStockCancel func(ctx context.Context, stock *entity.Stock) + afterStockCancelCounter uint64 + beforeStockCancelCounter uint64 + StockCancelMock mStockRepositoryMockStockCancel + + funcStockGetByID func(ctx context.Context, sku entity.Sku) (sp1 *entity.Stock, err error) + funcStockGetByIDOrigin string + inspectFuncStockGetByID func(ctx context.Context, sku entity.Sku) + afterStockGetByIDCounter uint64 + beforeStockGetByIDCounter uint64 + StockGetByIDMock mStockRepositoryMockStockGetByID + + funcStockReserve func(ctx context.Context, stock *entity.Stock) (err error) + funcStockReserveOrigin string + inspectFuncStockReserve func(ctx context.Context, stock *entity.Stock) + afterStockReserveCounter uint64 + beforeStockReserveCounter uint64 + StockReserveMock mStockRepositoryMockStockReserve + + funcStockReserveRemove func(ctx context.Context, stock *entity.Stock) (err error) + funcStockReserveRemoveOrigin string + inspectFuncStockReserveRemove func(ctx context.Context, stock *entity.Stock) + afterStockReserveRemoveCounter uint64 + beforeStockReserveRemoveCounter uint64 + StockReserveRemoveMock mStockRepositoryMockStockReserveRemove +} + +// NewStockRepositoryMock returns a mock for mm_service.StockRepository +func NewStockRepositoryMock(t minimock.Tester) *StockRepositoryMock { + m := &StockRepositoryMock{t: t} + + if controller, ok := t.(minimock.MockController); ok { + controller.RegisterMocker(m) + } + + m.StockCancelMock = mStockRepositoryMockStockCancel{mock: m} + m.StockCancelMock.callArgs = []*StockRepositoryMockStockCancelParams{} + + m.StockGetByIDMock = mStockRepositoryMockStockGetByID{mock: m} + m.StockGetByIDMock.callArgs = []*StockRepositoryMockStockGetByIDParams{} + + m.StockReserveMock = mStockRepositoryMockStockReserve{mock: m} + m.StockReserveMock.callArgs = []*StockRepositoryMockStockReserveParams{} + + m.StockReserveRemoveMock = mStockRepositoryMockStockReserveRemove{mock: m} + m.StockReserveRemoveMock.callArgs = []*StockRepositoryMockStockReserveRemoveParams{} + + t.Cleanup(m.MinimockFinish) + + return m +} + +type mStockRepositoryMockStockCancel struct { + optional bool + mock *StockRepositoryMock + defaultExpectation *StockRepositoryMockStockCancelExpectation + expectations []*StockRepositoryMockStockCancelExpectation + + callArgs []*StockRepositoryMockStockCancelParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// StockRepositoryMockStockCancelExpectation specifies expectation struct of the StockRepository.StockCancel +type StockRepositoryMockStockCancelExpectation struct { + mock *StockRepositoryMock + params *StockRepositoryMockStockCancelParams + paramPtrs *StockRepositoryMockStockCancelParamPtrs + expectationOrigins StockRepositoryMockStockCancelExpectationOrigins + results *StockRepositoryMockStockCancelResults + returnOrigin string + Counter uint64 +} + +// StockRepositoryMockStockCancelParams contains parameters of the StockRepository.StockCancel +type StockRepositoryMockStockCancelParams struct { + ctx context.Context + stock *entity.Stock +} + +// StockRepositoryMockStockCancelParamPtrs contains pointers to parameters of the StockRepository.StockCancel +type StockRepositoryMockStockCancelParamPtrs struct { + ctx *context.Context + stock **entity.Stock +} + +// StockRepositoryMockStockCancelResults contains results of the StockRepository.StockCancel +type StockRepositoryMockStockCancelResults struct { + err error +} + +// StockRepositoryMockStockCancelOrigins contains origins of expectations of the StockRepository.StockCancel +type StockRepositoryMockStockCancelExpectationOrigins struct { + origin string + originCtx string + originStock string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmStockCancel *mStockRepositoryMockStockCancel) Optional() *mStockRepositoryMockStockCancel { + mmStockCancel.optional = true + return mmStockCancel +} + +// Expect sets up expected params for StockRepository.StockCancel +func (mmStockCancel *mStockRepositoryMockStockCancel) Expect(ctx context.Context, stock *entity.Stock) *mStockRepositoryMockStockCancel { + if mmStockCancel.mock.funcStockCancel != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Set") + } + + if mmStockCancel.defaultExpectation == nil { + mmStockCancel.defaultExpectation = &StockRepositoryMockStockCancelExpectation{} + } + + if mmStockCancel.defaultExpectation.paramPtrs != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by ExpectParams functions") + } + + mmStockCancel.defaultExpectation.params = &StockRepositoryMockStockCancelParams{ctx, stock} + mmStockCancel.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmStockCancel.expectations { + if minimock.Equal(e.params, mmStockCancel.defaultExpectation.params) { + mmStockCancel.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmStockCancel.defaultExpectation.params) + } + } + + return mmStockCancel +} + +// ExpectCtxParam1 sets up expected param ctx for StockRepository.StockCancel +func (mmStockCancel *mStockRepositoryMockStockCancel) ExpectCtxParam1(ctx context.Context) *mStockRepositoryMockStockCancel { + if mmStockCancel.mock.funcStockCancel != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Set") + } + + if mmStockCancel.defaultExpectation == nil { + mmStockCancel.defaultExpectation = &StockRepositoryMockStockCancelExpectation{} + } + + if mmStockCancel.defaultExpectation.params != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Expect") + } + + if mmStockCancel.defaultExpectation.paramPtrs == nil { + mmStockCancel.defaultExpectation.paramPtrs = &StockRepositoryMockStockCancelParamPtrs{} + } + mmStockCancel.defaultExpectation.paramPtrs.ctx = &ctx + mmStockCancel.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmStockCancel +} + +// ExpectStockParam2 sets up expected param stock for StockRepository.StockCancel +func (mmStockCancel *mStockRepositoryMockStockCancel) ExpectStockParam2(stock *entity.Stock) *mStockRepositoryMockStockCancel { + if mmStockCancel.mock.funcStockCancel != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Set") + } + + if mmStockCancel.defaultExpectation == nil { + mmStockCancel.defaultExpectation = &StockRepositoryMockStockCancelExpectation{} + } + + if mmStockCancel.defaultExpectation.params != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Expect") + } + + if mmStockCancel.defaultExpectation.paramPtrs == nil { + mmStockCancel.defaultExpectation.paramPtrs = &StockRepositoryMockStockCancelParamPtrs{} + } + mmStockCancel.defaultExpectation.paramPtrs.stock = &stock + mmStockCancel.defaultExpectation.expectationOrigins.originStock = minimock.CallerInfo(1) + + return mmStockCancel +} + +// Inspect accepts an inspector function that has same arguments as the StockRepository.StockCancel +func (mmStockCancel *mStockRepositoryMockStockCancel) Inspect(f func(ctx context.Context, stock *entity.Stock)) *mStockRepositoryMockStockCancel { + if mmStockCancel.mock.inspectFuncStockCancel != nil { + mmStockCancel.mock.t.Fatalf("Inspect function is already set for StockRepositoryMock.StockCancel") + } + + mmStockCancel.mock.inspectFuncStockCancel = f + + return mmStockCancel +} + +// Return sets up results that will be returned by StockRepository.StockCancel +func (mmStockCancel *mStockRepositoryMockStockCancel) Return(err error) *StockRepositoryMock { + if mmStockCancel.mock.funcStockCancel != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Set") + } + + if mmStockCancel.defaultExpectation == nil { + mmStockCancel.defaultExpectation = &StockRepositoryMockStockCancelExpectation{mock: mmStockCancel.mock} + } + mmStockCancel.defaultExpectation.results = &StockRepositoryMockStockCancelResults{err} + mmStockCancel.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmStockCancel.mock +} + +// Set uses given function f to mock the StockRepository.StockCancel method +func (mmStockCancel *mStockRepositoryMockStockCancel) Set(f func(ctx context.Context, stock *entity.Stock) (err error)) *StockRepositoryMock { + if mmStockCancel.defaultExpectation != nil { + mmStockCancel.mock.t.Fatalf("Default expectation is already set for the StockRepository.StockCancel method") + } + + if len(mmStockCancel.expectations) > 0 { + mmStockCancel.mock.t.Fatalf("Some expectations are already set for the StockRepository.StockCancel method") + } + + mmStockCancel.mock.funcStockCancel = f + mmStockCancel.mock.funcStockCancelOrigin = minimock.CallerInfo(1) + return mmStockCancel.mock +} + +// When sets expectation for the StockRepository.StockCancel which will trigger the result defined by the following +// Then helper +func (mmStockCancel *mStockRepositoryMockStockCancel) When(ctx context.Context, stock *entity.Stock) *StockRepositoryMockStockCancelExpectation { + if mmStockCancel.mock.funcStockCancel != nil { + mmStockCancel.mock.t.Fatalf("StockRepositoryMock.StockCancel mock is already set by Set") + } + + expectation := &StockRepositoryMockStockCancelExpectation{ + mock: mmStockCancel.mock, + params: &StockRepositoryMockStockCancelParams{ctx, stock}, + expectationOrigins: StockRepositoryMockStockCancelExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmStockCancel.expectations = append(mmStockCancel.expectations, expectation) + return expectation +} + +// Then sets up StockRepository.StockCancel return parameters for the expectation previously defined by the When method +func (e *StockRepositoryMockStockCancelExpectation) Then(err error) *StockRepositoryMock { + e.results = &StockRepositoryMockStockCancelResults{err} + return e.mock +} + +// Times sets number of times StockRepository.StockCancel should be invoked +func (mmStockCancel *mStockRepositoryMockStockCancel) Times(n uint64) *mStockRepositoryMockStockCancel { + if n == 0 { + mmStockCancel.mock.t.Fatalf("Times of StockRepositoryMock.StockCancel mock can not be zero") + } + mm_atomic.StoreUint64(&mmStockCancel.expectedInvocations, n) + mmStockCancel.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmStockCancel +} + +func (mmStockCancel *mStockRepositoryMockStockCancel) invocationsDone() bool { + if len(mmStockCancel.expectations) == 0 && mmStockCancel.defaultExpectation == nil && mmStockCancel.mock.funcStockCancel == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmStockCancel.mock.afterStockCancelCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmStockCancel.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// StockCancel implements mm_service.StockRepository +func (mmStockCancel *StockRepositoryMock) StockCancel(ctx context.Context, stock *entity.Stock) (err error) { + mm_atomic.AddUint64(&mmStockCancel.beforeStockCancelCounter, 1) + defer mm_atomic.AddUint64(&mmStockCancel.afterStockCancelCounter, 1) + + mmStockCancel.t.Helper() + + if mmStockCancel.inspectFuncStockCancel != nil { + mmStockCancel.inspectFuncStockCancel(ctx, stock) + } + + mm_params := StockRepositoryMockStockCancelParams{ctx, stock} + + // Record call args + mmStockCancel.StockCancelMock.mutex.Lock() + mmStockCancel.StockCancelMock.callArgs = append(mmStockCancel.StockCancelMock.callArgs, &mm_params) + mmStockCancel.StockCancelMock.mutex.Unlock() + + for _, e := range mmStockCancel.StockCancelMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.err + } + } + + if mmStockCancel.StockCancelMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmStockCancel.StockCancelMock.defaultExpectation.Counter, 1) + mm_want := mmStockCancel.StockCancelMock.defaultExpectation.params + mm_want_ptrs := mmStockCancel.StockCancelMock.defaultExpectation.paramPtrs + + mm_got := StockRepositoryMockStockCancelParams{ctx, stock} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmStockCancel.t.Errorf("StockRepositoryMock.StockCancel got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockCancel.StockCancelMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.stock != nil && !minimock.Equal(*mm_want_ptrs.stock, mm_got.stock) { + mmStockCancel.t.Errorf("StockRepositoryMock.StockCancel got unexpected parameter stock, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockCancel.StockCancelMock.defaultExpectation.expectationOrigins.originStock, *mm_want_ptrs.stock, mm_got.stock, minimock.Diff(*mm_want_ptrs.stock, mm_got.stock)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmStockCancel.t.Errorf("StockRepositoryMock.StockCancel got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockCancel.StockCancelMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmStockCancel.StockCancelMock.defaultExpectation.results + if mm_results == nil { + mmStockCancel.t.Fatal("No results are set for the StockRepositoryMock.StockCancel") + } + return (*mm_results).err + } + if mmStockCancel.funcStockCancel != nil { + return mmStockCancel.funcStockCancel(ctx, stock) + } + mmStockCancel.t.Fatalf("Unexpected call to StockRepositoryMock.StockCancel. %v %v", ctx, stock) + return +} + +// StockCancelAfterCounter returns a count of finished StockRepositoryMock.StockCancel invocations +func (mmStockCancel *StockRepositoryMock) StockCancelAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockCancel.afterStockCancelCounter) +} + +// StockCancelBeforeCounter returns a count of StockRepositoryMock.StockCancel invocations +func (mmStockCancel *StockRepositoryMock) StockCancelBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockCancel.beforeStockCancelCounter) +} + +// Calls returns a list of arguments used in each call to StockRepositoryMock.StockCancel. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmStockCancel *mStockRepositoryMockStockCancel) Calls() []*StockRepositoryMockStockCancelParams { + mmStockCancel.mutex.RLock() + + argCopy := make([]*StockRepositoryMockStockCancelParams, len(mmStockCancel.callArgs)) + copy(argCopy, mmStockCancel.callArgs) + + mmStockCancel.mutex.RUnlock() + + return argCopy +} + +// MinimockStockCancelDone returns true if the count of the StockCancel invocations corresponds +// the number of defined expectations +func (m *StockRepositoryMock) MinimockStockCancelDone() bool { + if m.StockCancelMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.StockCancelMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.StockCancelMock.invocationsDone() +} + +// MinimockStockCancelInspect logs each unmet expectation +func (m *StockRepositoryMock) MinimockStockCancelInspect() { + for _, e := range m.StockCancelMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockCancel at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterStockCancelCounter := mm_atomic.LoadUint64(&m.afterStockCancelCounter) + // if default expectation was set then invocations count should be greater than zero + if m.StockCancelMock.defaultExpectation != nil && afterStockCancelCounter < 1 { + if m.StockCancelMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to StockRepositoryMock.StockCancel at\n%s", m.StockCancelMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to StockRepositoryMock.StockCancel at\n%s with params: %#v", m.StockCancelMock.defaultExpectation.expectationOrigins.origin, *m.StockCancelMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcStockCancel != nil && afterStockCancelCounter < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockCancel at\n%s", m.funcStockCancelOrigin) + } + + if !m.StockCancelMock.invocationsDone() && afterStockCancelCounter > 0 { + m.t.Errorf("Expected %d calls to StockRepositoryMock.StockCancel at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.StockCancelMock.expectedInvocations), m.StockCancelMock.expectedInvocationsOrigin, afterStockCancelCounter) + } +} + +type mStockRepositoryMockStockGetByID struct { + optional bool + mock *StockRepositoryMock + defaultExpectation *StockRepositoryMockStockGetByIDExpectation + expectations []*StockRepositoryMockStockGetByIDExpectation + + callArgs []*StockRepositoryMockStockGetByIDParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// StockRepositoryMockStockGetByIDExpectation specifies expectation struct of the StockRepository.StockGetByID +type StockRepositoryMockStockGetByIDExpectation struct { + mock *StockRepositoryMock + params *StockRepositoryMockStockGetByIDParams + paramPtrs *StockRepositoryMockStockGetByIDParamPtrs + expectationOrigins StockRepositoryMockStockGetByIDExpectationOrigins + results *StockRepositoryMockStockGetByIDResults + returnOrigin string + Counter uint64 +} + +// StockRepositoryMockStockGetByIDParams contains parameters of the StockRepository.StockGetByID +type StockRepositoryMockStockGetByIDParams struct { + ctx context.Context + sku entity.Sku +} + +// StockRepositoryMockStockGetByIDParamPtrs contains pointers to parameters of the StockRepository.StockGetByID +type StockRepositoryMockStockGetByIDParamPtrs struct { + ctx *context.Context + sku *entity.Sku +} + +// StockRepositoryMockStockGetByIDResults contains results of the StockRepository.StockGetByID +type StockRepositoryMockStockGetByIDResults struct { + sp1 *entity.Stock + err error +} + +// StockRepositoryMockStockGetByIDOrigins contains origins of expectations of the StockRepository.StockGetByID +type StockRepositoryMockStockGetByIDExpectationOrigins struct { + origin string + originCtx string + originSku string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Optional() *mStockRepositoryMockStockGetByID { + mmStockGetByID.optional = true + return mmStockGetByID +} + +// Expect sets up expected params for StockRepository.StockGetByID +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Expect(ctx context.Context, sku entity.Sku) *mStockRepositoryMockStockGetByID { + if mmStockGetByID.mock.funcStockGetByID != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Set") + } + + if mmStockGetByID.defaultExpectation == nil { + mmStockGetByID.defaultExpectation = &StockRepositoryMockStockGetByIDExpectation{} + } + + if mmStockGetByID.defaultExpectation.paramPtrs != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by ExpectParams functions") + } + + mmStockGetByID.defaultExpectation.params = &StockRepositoryMockStockGetByIDParams{ctx, sku} + mmStockGetByID.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmStockGetByID.expectations { + if minimock.Equal(e.params, mmStockGetByID.defaultExpectation.params) { + mmStockGetByID.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmStockGetByID.defaultExpectation.params) + } + } + + return mmStockGetByID +} + +// ExpectCtxParam1 sets up expected param ctx for StockRepository.StockGetByID +func (mmStockGetByID *mStockRepositoryMockStockGetByID) ExpectCtxParam1(ctx context.Context) *mStockRepositoryMockStockGetByID { + if mmStockGetByID.mock.funcStockGetByID != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Set") + } + + if mmStockGetByID.defaultExpectation == nil { + mmStockGetByID.defaultExpectation = &StockRepositoryMockStockGetByIDExpectation{} + } + + if mmStockGetByID.defaultExpectation.params != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Expect") + } + + if mmStockGetByID.defaultExpectation.paramPtrs == nil { + mmStockGetByID.defaultExpectation.paramPtrs = &StockRepositoryMockStockGetByIDParamPtrs{} + } + mmStockGetByID.defaultExpectation.paramPtrs.ctx = &ctx + mmStockGetByID.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmStockGetByID +} + +// ExpectSkuParam2 sets up expected param sku for StockRepository.StockGetByID +func (mmStockGetByID *mStockRepositoryMockStockGetByID) ExpectSkuParam2(sku entity.Sku) *mStockRepositoryMockStockGetByID { + if mmStockGetByID.mock.funcStockGetByID != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Set") + } + + if mmStockGetByID.defaultExpectation == nil { + mmStockGetByID.defaultExpectation = &StockRepositoryMockStockGetByIDExpectation{} + } + + if mmStockGetByID.defaultExpectation.params != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Expect") + } + + if mmStockGetByID.defaultExpectation.paramPtrs == nil { + mmStockGetByID.defaultExpectation.paramPtrs = &StockRepositoryMockStockGetByIDParamPtrs{} + } + mmStockGetByID.defaultExpectation.paramPtrs.sku = &sku + mmStockGetByID.defaultExpectation.expectationOrigins.originSku = minimock.CallerInfo(1) + + return mmStockGetByID +} + +// Inspect accepts an inspector function that has same arguments as the StockRepository.StockGetByID +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Inspect(f func(ctx context.Context, sku entity.Sku)) *mStockRepositoryMockStockGetByID { + if mmStockGetByID.mock.inspectFuncStockGetByID != nil { + mmStockGetByID.mock.t.Fatalf("Inspect function is already set for StockRepositoryMock.StockGetByID") + } + + mmStockGetByID.mock.inspectFuncStockGetByID = f + + return mmStockGetByID +} + +// Return sets up results that will be returned by StockRepository.StockGetByID +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Return(sp1 *entity.Stock, err error) *StockRepositoryMock { + if mmStockGetByID.mock.funcStockGetByID != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Set") + } + + if mmStockGetByID.defaultExpectation == nil { + mmStockGetByID.defaultExpectation = &StockRepositoryMockStockGetByIDExpectation{mock: mmStockGetByID.mock} + } + mmStockGetByID.defaultExpectation.results = &StockRepositoryMockStockGetByIDResults{sp1, err} + mmStockGetByID.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmStockGetByID.mock +} + +// Set uses given function f to mock the StockRepository.StockGetByID method +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Set(f func(ctx context.Context, sku entity.Sku) (sp1 *entity.Stock, err error)) *StockRepositoryMock { + if mmStockGetByID.defaultExpectation != nil { + mmStockGetByID.mock.t.Fatalf("Default expectation is already set for the StockRepository.StockGetByID method") + } + + if len(mmStockGetByID.expectations) > 0 { + mmStockGetByID.mock.t.Fatalf("Some expectations are already set for the StockRepository.StockGetByID method") + } + + mmStockGetByID.mock.funcStockGetByID = f + mmStockGetByID.mock.funcStockGetByIDOrigin = minimock.CallerInfo(1) + return mmStockGetByID.mock +} + +// When sets expectation for the StockRepository.StockGetByID which will trigger the result defined by the following +// Then helper +func (mmStockGetByID *mStockRepositoryMockStockGetByID) When(ctx context.Context, sku entity.Sku) *StockRepositoryMockStockGetByIDExpectation { + if mmStockGetByID.mock.funcStockGetByID != nil { + mmStockGetByID.mock.t.Fatalf("StockRepositoryMock.StockGetByID mock is already set by Set") + } + + expectation := &StockRepositoryMockStockGetByIDExpectation{ + mock: mmStockGetByID.mock, + params: &StockRepositoryMockStockGetByIDParams{ctx, sku}, + expectationOrigins: StockRepositoryMockStockGetByIDExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmStockGetByID.expectations = append(mmStockGetByID.expectations, expectation) + return expectation +} + +// Then sets up StockRepository.StockGetByID return parameters for the expectation previously defined by the When method +func (e *StockRepositoryMockStockGetByIDExpectation) Then(sp1 *entity.Stock, err error) *StockRepositoryMock { + e.results = &StockRepositoryMockStockGetByIDResults{sp1, err} + return e.mock +} + +// Times sets number of times StockRepository.StockGetByID should be invoked +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Times(n uint64) *mStockRepositoryMockStockGetByID { + if n == 0 { + mmStockGetByID.mock.t.Fatalf("Times of StockRepositoryMock.StockGetByID mock can not be zero") + } + mm_atomic.StoreUint64(&mmStockGetByID.expectedInvocations, n) + mmStockGetByID.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmStockGetByID +} + +func (mmStockGetByID *mStockRepositoryMockStockGetByID) invocationsDone() bool { + if len(mmStockGetByID.expectations) == 0 && mmStockGetByID.defaultExpectation == nil && mmStockGetByID.mock.funcStockGetByID == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmStockGetByID.mock.afterStockGetByIDCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmStockGetByID.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// StockGetByID implements mm_service.StockRepository +func (mmStockGetByID *StockRepositoryMock) StockGetByID(ctx context.Context, sku entity.Sku) (sp1 *entity.Stock, err error) { + mm_atomic.AddUint64(&mmStockGetByID.beforeStockGetByIDCounter, 1) + defer mm_atomic.AddUint64(&mmStockGetByID.afterStockGetByIDCounter, 1) + + mmStockGetByID.t.Helper() + + if mmStockGetByID.inspectFuncStockGetByID != nil { + mmStockGetByID.inspectFuncStockGetByID(ctx, sku) + } + + mm_params := StockRepositoryMockStockGetByIDParams{ctx, sku} + + // Record call args + mmStockGetByID.StockGetByIDMock.mutex.Lock() + mmStockGetByID.StockGetByIDMock.callArgs = append(mmStockGetByID.StockGetByIDMock.callArgs, &mm_params) + mmStockGetByID.StockGetByIDMock.mutex.Unlock() + + for _, e := range mmStockGetByID.StockGetByIDMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.sp1, e.results.err + } + } + + if mmStockGetByID.StockGetByIDMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmStockGetByID.StockGetByIDMock.defaultExpectation.Counter, 1) + mm_want := mmStockGetByID.StockGetByIDMock.defaultExpectation.params + mm_want_ptrs := mmStockGetByID.StockGetByIDMock.defaultExpectation.paramPtrs + + mm_got := StockRepositoryMockStockGetByIDParams{ctx, sku} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmStockGetByID.t.Errorf("StockRepositoryMock.StockGetByID got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockGetByID.StockGetByIDMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.sku != nil && !minimock.Equal(*mm_want_ptrs.sku, mm_got.sku) { + mmStockGetByID.t.Errorf("StockRepositoryMock.StockGetByID got unexpected parameter sku, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockGetByID.StockGetByIDMock.defaultExpectation.expectationOrigins.originSku, *mm_want_ptrs.sku, mm_got.sku, minimock.Diff(*mm_want_ptrs.sku, mm_got.sku)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmStockGetByID.t.Errorf("StockRepositoryMock.StockGetByID got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockGetByID.StockGetByIDMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmStockGetByID.StockGetByIDMock.defaultExpectation.results + if mm_results == nil { + mmStockGetByID.t.Fatal("No results are set for the StockRepositoryMock.StockGetByID") + } + return (*mm_results).sp1, (*mm_results).err + } + if mmStockGetByID.funcStockGetByID != nil { + return mmStockGetByID.funcStockGetByID(ctx, sku) + } + mmStockGetByID.t.Fatalf("Unexpected call to StockRepositoryMock.StockGetByID. %v %v", ctx, sku) + return +} + +// StockGetByIDAfterCounter returns a count of finished StockRepositoryMock.StockGetByID invocations +func (mmStockGetByID *StockRepositoryMock) StockGetByIDAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockGetByID.afterStockGetByIDCounter) +} + +// StockGetByIDBeforeCounter returns a count of StockRepositoryMock.StockGetByID invocations +func (mmStockGetByID *StockRepositoryMock) StockGetByIDBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockGetByID.beforeStockGetByIDCounter) +} + +// Calls returns a list of arguments used in each call to StockRepositoryMock.StockGetByID. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmStockGetByID *mStockRepositoryMockStockGetByID) Calls() []*StockRepositoryMockStockGetByIDParams { + mmStockGetByID.mutex.RLock() + + argCopy := make([]*StockRepositoryMockStockGetByIDParams, len(mmStockGetByID.callArgs)) + copy(argCopy, mmStockGetByID.callArgs) + + mmStockGetByID.mutex.RUnlock() + + return argCopy +} + +// MinimockStockGetByIDDone returns true if the count of the StockGetByID invocations corresponds +// the number of defined expectations +func (m *StockRepositoryMock) MinimockStockGetByIDDone() bool { + if m.StockGetByIDMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.StockGetByIDMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.StockGetByIDMock.invocationsDone() +} + +// MinimockStockGetByIDInspect logs each unmet expectation +func (m *StockRepositoryMock) MinimockStockGetByIDInspect() { + for _, e := range m.StockGetByIDMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockGetByID at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterStockGetByIDCounter := mm_atomic.LoadUint64(&m.afterStockGetByIDCounter) + // if default expectation was set then invocations count should be greater than zero + if m.StockGetByIDMock.defaultExpectation != nil && afterStockGetByIDCounter < 1 { + if m.StockGetByIDMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to StockRepositoryMock.StockGetByID at\n%s", m.StockGetByIDMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to StockRepositoryMock.StockGetByID at\n%s with params: %#v", m.StockGetByIDMock.defaultExpectation.expectationOrigins.origin, *m.StockGetByIDMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcStockGetByID != nil && afterStockGetByIDCounter < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockGetByID at\n%s", m.funcStockGetByIDOrigin) + } + + if !m.StockGetByIDMock.invocationsDone() && afterStockGetByIDCounter > 0 { + m.t.Errorf("Expected %d calls to StockRepositoryMock.StockGetByID at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.StockGetByIDMock.expectedInvocations), m.StockGetByIDMock.expectedInvocationsOrigin, afterStockGetByIDCounter) + } +} + +type mStockRepositoryMockStockReserve struct { + optional bool + mock *StockRepositoryMock + defaultExpectation *StockRepositoryMockStockReserveExpectation + expectations []*StockRepositoryMockStockReserveExpectation + + callArgs []*StockRepositoryMockStockReserveParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// StockRepositoryMockStockReserveExpectation specifies expectation struct of the StockRepository.StockReserve +type StockRepositoryMockStockReserveExpectation struct { + mock *StockRepositoryMock + params *StockRepositoryMockStockReserveParams + paramPtrs *StockRepositoryMockStockReserveParamPtrs + expectationOrigins StockRepositoryMockStockReserveExpectationOrigins + results *StockRepositoryMockStockReserveResults + returnOrigin string + Counter uint64 +} + +// StockRepositoryMockStockReserveParams contains parameters of the StockRepository.StockReserve +type StockRepositoryMockStockReserveParams struct { + ctx context.Context + stock *entity.Stock +} + +// StockRepositoryMockStockReserveParamPtrs contains pointers to parameters of the StockRepository.StockReserve +type StockRepositoryMockStockReserveParamPtrs struct { + ctx *context.Context + stock **entity.Stock +} + +// StockRepositoryMockStockReserveResults contains results of the StockRepository.StockReserve +type StockRepositoryMockStockReserveResults struct { + err error +} + +// StockRepositoryMockStockReserveOrigins contains origins of expectations of the StockRepository.StockReserve +type StockRepositoryMockStockReserveExpectationOrigins struct { + origin string + originCtx string + originStock string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmStockReserve *mStockRepositoryMockStockReserve) Optional() *mStockRepositoryMockStockReserve { + mmStockReserve.optional = true + return mmStockReserve +} + +// Expect sets up expected params for StockRepository.StockReserve +func (mmStockReserve *mStockRepositoryMockStockReserve) Expect(ctx context.Context, stock *entity.Stock) *mStockRepositoryMockStockReserve { + if mmStockReserve.mock.funcStockReserve != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Set") + } + + if mmStockReserve.defaultExpectation == nil { + mmStockReserve.defaultExpectation = &StockRepositoryMockStockReserveExpectation{} + } + + if mmStockReserve.defaultExpectation.paramPtrs != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by ExpectParams functions") + } + + mmStockReserve.defaultExpectation.params = &StockRepositoryMockStockReserveParams{ctx, stock} + mmStockReserve.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmStockReserve.expectations { + if minimock.Equal(e.params, mmStockReserve.defaultExpectation.params) { + mmStockReserve.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmStockReserve.defaultExpectation.params) + } + } + + return mmStockReserve +} + +// ExpectCtxParam1 sets up expected param ctx for StockRepository.StockReserve +func (mmStockReserve *mStockRepositoryMockStockReserve) ExpectCtxParam1(ctx context.Context) *mStockRepositoryMockStockReserve { + if mmStockReserve.mock.funcStockReserve != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Set") + } + + if mmStockReserve.defaultExpectation == nil { + mmStockReserve.defaultExpectation = &StockRepositoryMockStockReserveExpectation{} + } + + if mmStockReserve.defaultExpectation.params != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Expect") + } + + if mmStockReserve.defaultExpectation.paramPtrs == nil { + mmStockReserve.defaultExpectation.paramPtrs = &StockRepositoryMockStockReserveParamPtrs{} + } + mmStockReserve.defaultExpectation.paramPtrs.ctx = &ctx + mmStockReserve.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmStockReserve +} + +// ExpectStockParam2 sets up expected param stock for StockRepository.StockReserve +func (mmStockReserve *mStockRepositoryMockStockReserve) ExpectStockParam2(stock *entity.Stock) *mStockRepositoryMockStockReserve { + if mmStockReserve.mock.funcStockReserve != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Set") + } + + if mmStockReserve.defaultExpectation == nil { + mmStockReserve.defaultExpectation = &StockRepositoryMockStockReserveExpectation{} + } + + if mmStockReserve.defaultExpectation.params != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Expect") + } + + if mmStockReserve.defaultExpectation.paramPtrs == nil { + mmStockReserve.defaultExpectation.paramPtrs = &StockRepositoryMockStockReserveParamPtrs{} + } + mmStockReserve.defaultExpectation.paramPtrs.stock = &stock + mmStockReserve.defaultExpectation.expectationOrigins.originStock = minimock.CallerInfo(1) + + return mmStockReserve +} + +// Inspect accepts an inspector function that has same arguments as the StockRepository.StockReserve +func (mmStockReserve *mStockRepositoryMockStockReserve) Inspect(f func(ctx context.Context, stock *entity.Stock)) *mStockRepositoryMockStockReserve { + if mmStockReserve.mock.inspectFuncStockReserve != nil { + mmStockReserve.mock.t.Fatalf("Inspect function is already set for StockRepositoryMock.StockReserve") + } + + mmStockReserve.mock.inspectFuncStockReserve = f + + return mmStockReserve +} + +// Return sets up results that will be returned by StockRepository.StockReserve +func (mmStockReserve *mStockRepositoryMockStockReserve) Return(err error) *StockRepositoryMock { + if mmStockReserve.mock.funcStockReserve != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Set") + } + + if mmStockReserve.defaultExpectation == nil { + mmStockReserve.defaultExpectation = &StockRepositoryMockStockReserveExpectation{mock: mmStockReserve.mock} + } + mmStockReserve.defaultExpectation.results = &StockRepositoryMockStockReserveResults{err} + mmStockReserve.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmStockReserve.mock +} + +// Set uses given function f to mock the StockRepository.StockReserve method +func (mmStockReserve *mStockRepositoryMockStockReserve) Set(f func(ctx context.Context, stock *entity.Stock) (err error)) *StockRepositoryMock { + if mmStockReserve.defaultExpectation != nil { + mmStockReserve.mock.t.Fatalf("Default expectation is already set for the StockRepository.StockReserve method") + } + + if len(mmStockReserve.expectations) > 0 { + mmStockReserve.mock.t.Fatalf("Some expectations are already set for the StockRepository.StockReserve method") + } + + mmStockReserve.mock.funcStockReserve = f + mmStockReserve.mock.funcStockReserveOrigin = minimock.CallerInfo(1) + return mmStockReserve.mock +} + +// When sets expectation for the StockRepository.StockReserve which will trigger the result defined by the following +// Then helper +func (mmStockReserve *mStockRepositoryMockStockReserve) When(ctx context.Context, stock *entity.Stock) *StockRepositoryMockStockReserveExpectation { + if mmStockReserve.mock.funcStockReserve != nil { + mmStockReserve.mock.t.Fatalf("StockRepositoryMock.StockReserve mock is already set by Set") + } + + expectation := &StockRepositoryMockStockReserveExpectation{ + mock: mmStockReserve.mock, + params: &StockRepositoryMockStockReserveParams{ctx, stock}, + expectationOrigins: StockRepositoryMockStockReserveExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmStockReserve.expectations = append(mmStockReserve.expectations, expectation) + return expectation +} + +// Then sets up StockRepository.StockReserve return parameters for the expectation previously defined by the When method +func (e *StockRepositoryMockStockReserveExpectation) Then(err error) *StockRepositoryMock { + e.results = &StockRepositoryMockStockReserveResults{err} + return e.mock +} + +// Times sets number of times StockRepository.StockReserve should be invoked +func (mmStockReserve *mStockRepositoryMockStockReserve) Times(n uint64) *mStockRepositoryMockStockReserve { + if n == 0 { + mmStockReserve.mock.t.Fatalf("Times of StockRepositoryMock.StockReserve mock can not be zero") + } + mm_atomic.StoreUint64(&mmStockReserve.expectedInvocations, n) + mmStockReserve.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmStockReserve +} + +func (mmStockReserve *mStockRepositoryMockStockReserve) invocationsDone() bool { + if len(mmStockReserve.expectations) == 0 && mmStockReserve.defaultExpectation == nil && mmStockReserve.mock.funcStockReserve == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmStockReserve.mock.afterStockReserveCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmStockReserve.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// StockReserve implements mm_service.StockRepository +func (mmStockReserve *StockRepositoryMock) StockReserve(ctx context.Context, stock *entity.Stock) (err error) { + mm_atomic.AddUint64(&mmStockReserve.beforeStockReserveCounter, 1) + defer mm_atomic.AddUint64(&mmStockReserve.afterStockReserveCounter, 1) + + mmStockReserve.t.Helper() + + if mmStockReserve.inspectFuncStockReserve != nil { + mmStockReserve.inspectFuncStockReserve(ctx, stock) + } + + mm_params := StockRepositoryMockStockReserveParams{ctx, stock} + + // Record call args + mmStockReserve.StockReserveMock.mutex.Lock() + mmStockReserve.StockReserveMock.callArgs = append(mmStockReserve.StockReserveMock.callArgs, &mm_params) + mmStockReserve.StockReserveMock.mutex.Unlock() + + for _, e := range mmStockReserve.StockReserveMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.err + } + } + + if mmStockReserve.StockReserveMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmStockReserve.StockReserveMock.defaultExpectation.Counter, 1) + mm_want := mmStockReserve.StockReserveMock.defaultExpectation.params + mm_want_ptrs := mmStockReserve.StockReserveMock.defaultExpectation.paramPtrs + + mm_got := StockRepositoryMockStockReserveParams{ctx, stock} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmStockReserve.t.Errorf("StockRepositoryMock.StockReserve got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockReserve.StockReserveMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.stock != nil && !minimock.Equal(*mm_want_ptrs.stock, mm_got.stock) { + mmStockReserve.t.Errorf("StockRepositoryMock.StockReserve got unexpected parameter stock, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockReserve.StockReserveMock.defaultExpectation.expectationOrigins.originStock, *mm_want_ptrs.stock, mm_got.stock, minimock.Diff(*mm_want_ptrs.stock, mm_got.stock)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmStockReserve.t.Errorf("StockRepositoryMock.StockReserve got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockReserve.StockReserveMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmStockReserve.StockReserveMock.defaultExpectation.results + if mm_results == nil { + mmStockReserve.t.Fatal("No results are set for the StockRepositoryMock.StockReserve") + } + return (*mm_results).err + } + if mmStockReserve.funcStockReserve != nil { + return mmStockReserve.funcStockReserve(ctx, stock) + } + mmStockReserve.t.Fatalf("Unexpected call to StockRepositoryMock.StockReserve. %v %v", ctx, stock) + return +} + +// StockReserveAfterCounter returns a count of finished StockRepositoryMock.StockReserve invocations +func (mmStockReserve *StockRepositoryMock) StockReserveAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockReserve.afterStockReserveCounter) +} + +// StockReserveBeforeCounter returns a count of StockRepositoryMock.StockReserve invocations +func (mmStockReserve *StockRepositoryMock) StockReserveBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockReserve.beforeStockReserveCounter) +} + +// Calls returns a list of arguments used in each call to StockRepositoryMock.StockReserve. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmStockReserve *mStockRepositoryMockStockReserve) Calls() []*StockRepositoryMockStockReserveParams { + mmStockReserve.mutex.RLock() + + argCopy := make([]*StockRepositoryMockStockReserveParams, len(mmStockReserve.callArgs)) + copy(argCopy, mmStockReserve.callArgs) + + mmStockReserve.mutex.RUnlock() + + return argCopy +} + +// MinimockStockReserveDone returns true if the count of the StockReserve invocations corresponds +// the number of defined expectations +func (m *StockRepositoryMock) MinimockStockReserveDone() bool { + if m.StockReserveMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.StockReserveMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.StockReserveMock.invocationsDone() +} + +// MinimockStockReserveInspect logs each unmet expectation +func (m *StockRepositoryMock) MinimockStockReserveInspect() { + for _, e := range m.StockReserveMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserve at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterStockReserveCounter := mm_atomic.LoadUint64(&m.afterStockReserveCounter) + // if default expectation was set then invocations count should be greater than zero + if m.StockReserveMock.defaultExpectation != nil && afterStockReserveCounter < 1 { + if m.StockReserveMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserve at\n%s", m.StockReserveMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserve at\n%s with params: %#v", m.StockReserveMock.defaultExpectation.expectationOrigins.origin, *m.StockReserveMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcStockReserve != nil && afterStockReserveCounter < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserve at\n%s", m.funcStockReserveOrigin) + } + + if !m.StockReserveMock.invocationsDone() && afterStockReserveCounter > 0 { + m.t.Errorf("Expected %d calls to StockRepositoryMock.StockReserve at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.StockReserveMock.expectedInvocations), m.StockReserveMock.expectedInvocationsOrigin, afterStockReserveCounter) + } +} + +type mStockRepositoryMockStockReserveRemove struct { + optional bool + mock *StockRepositoryMock + defaultExpectation *StockRepositoryMockStockReserveRemoveExpectation + expectations []*StockRepositoryMockStockReserveRemoveExpectation + + callArgs []*StockRepositoryMockStockReserveRemoveParams + mutex sync.RWMutex + + expectedInvocations uint64 + expectedInvocationsOrigin string +} + +// StockRepositoryMockStockReserveRemoveExpectation specifies expectation struct of the StockRepository.StockReserveRemove +type StockRepositoryMockStockReserveRemoveExpectation struct { + mock *StockRepositoryMock + params *StockRepositoryMockStockReserveRemoveParams + paramPtrs *StockRepositoryMockStockReserveRemoveParamPtrs + expectationOrigins StockRepositoryMockStockReserveRemoveExpectationOrigins + results *StockRepositoryMockStockReserveRemoveResults + returnOrigin string + Counter uint64 +} + +// StockRepositoryMockStockReserveRemoveParams contains parameters of the StockRepository.StockReserveRemove +type StockRepositoryMockStockReserveRemoveParams struct { + ctx context.Context + stock *entity.Stock +} + +// StockRepositoryMockStockReserveRemoveParamPtrs contains pointers to parameters of the StockRepository.StockReserveRemove +type StockRepositoryMockStockReserveRemoveParamPtrs struct { + ctx *context.Context + stock **entity.Stock +} + +// StockRepositoryMockStockReserveRemoveResults contains results of the StockRepository.StockReserveRemove +type StockRepositoryMockStockReserveRemoveResults struct { + err error +} + +// StockRepositoryMockStockReserveRemoveOrigins contains origins of expectations of the StockRepository.StockReserveRemove +type StockRepositoryMockStockReserveRemoveExpectationOrigins struct { + origin string + originCtx string + originStock string +} + +// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning +// the test will fail minimock's automatic final call check if the mocked method was not called at least once. +// Optional() makes method check to work in '0 or more' mode. +// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to +// catch the problems when the expected method call is totally skipped during test run. +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Optional() *mStockRepositoryMockStockReserveRemove { + mmStockReserveRemove.optional = true + return mmStockReserveRemove +} + +// Expect sets up expected params for StockRepository.StockReserveRemove +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Expect(ctx context.Context, stock *entity.Stock) *mStockRepositoryMockStockReserveRemove { + if mmStockReserveRemove.mock.funcStockReserveRemove != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Set") + } + + if mmStockReserveRemove.defaultExpectation == nil { + mmStockReserveRemove.defaultExpectation = &StockRepositoryMockStockReserveRemoveExpectation{} + } + + if mmStockReserveRemove.defaultExpectation.paramPtrs != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by ExpectParams functions") + } + + mmStockReserveRemove.defaultExpectation.params = &StockRepositoryMockStockReserveRemoveParams{ctx, stock} + mmStockReserveRemove.defaultExpectation.expectationOrigins.origin = minimock.CallerInfo(1) + for _, e := range mmStockReserveRemove.expectations { + if minimock.Equal(e.params, mmStockReserveRemove.defaultExpectation.params) { + mmStockReserveRemove.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmStockReserveRemove.defaultExpectation.params) + } + } + + return mmStockReserveRemove +} + +// ExpectCtxParam1 sets up expected param ctx for StockRepository.StockReserveRemove +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) ExpectCtxParam1(ctx context.Context) *mStockRepositoryMockStockReserveRemove { + if mmStockReserveRemove.mock.funcStockReserveRemove != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Set") + } + + if mmStockReserveRemove.defaultExpectation == nil { + mmStockReserveRemove.defaultExpectation = &StockRepositoryMockStockReserveRemoveExpectation{} + } + + if mmStockReserveRemove.defaultExpectation.params != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Expect") + } + + if mmStockReserveRemove.defaultExpectation.paramPtrs == nil { + mmStockReserveRemove.defaultExpectation.paramPtrs = &StockRepositoryMockStockReserveRemoveParamPtrs{} + } + mmStockReserveRemove.defaultExpectation.paramPtrs.ctx = &ctx + mmStockReserveRemove.defaultExpectation.expectationOrigins.originCtx = minimock.CallerInfo(1) + + return mmStockReserveRemove +} + +// ExpectStockParam2 sets up expected param stock for StockRepository.StockReserveRemove +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) ExpectStockParam2(stock *entity.Stock) *mStockRepositoryMockStockReserveRemove { + if mmStockReserveRemove.mock.funcStockReserveRemove != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Set") + } + + if mmStockReserveRemove.defaultExpectation == nil { + mmStockReserveRemove.defaultExpectation = &StockRepositoryMockStockReserveRemoveExpectation{} + } + + if mmStockReserveRemove.defaultExpectation.params != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Expect") + } + + if mmStockReserveRemove.defaultExpectation.paramPtrs == nil { + mmStockReserveRemove.defaultExpectation.paramPtrs = &StockRepositoryMockStockReserveRemoveParamPtrs{} + } + mmStockReserveRemove.defaultExpectation.paramPtrs.stock = &stock + mmStockReserveRemove.defaultExpectation.expectationOrigins.originStock = minimock.CallerInfo(1) + + return mmStockReserveRemove +} + +// Inspect accepts an inspector function that has same arguments as the StockRepository.StockReserveRemove +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Inspect(f func(ctx context.Context, stock *entity.Stock)) *mStockRepositoryMockStockReserveRemove { + if mmStockReserveRemove.mock.inspectFuncStockReserveRemove != nil { + mmStockReserveRemove.mock.t.Fatalf("Inspect function is already set for StockRepositoryMock.StockReserveRemove") + } + + mmStockReserveRemove.mock.inspectFuncStockReserveRemove = f + + return mmStockReserveRemove +} + +// Return sets up results that will be returned by StockRepository.StockReserveRemove +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Return(err error) *StockRepositoryMock { + if mmStockReserveRemove.mock.funcStockReserveRemove != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Set") + } + + if mmStockReserveRemove.defaultExpectation == nil { + mmStockReserveRemove.defaultExpectation = &StockRepositoryMockStockReserveRemoveExpectation{mock: mmStockReserveRemove.mock} + } + mmStockReserveRemove.defaultExpectation.results = &StockRepositoryMockStockReserveRemoveResults{err} + mmStockReserveRemove.defaultExpectation.returnOrigin = minimock.CallerInfo(1) + return mmStockReserveRemove.mock +} + +// Set uses given function f to mock the StockRepository.StockReserveRemove method +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Set(f func(ctx context.Context, stock *entity.Stock) (err error)) *StockRepositoryMock { + if mmStockReserveRemove.defaultExpectation != nil { + mmStockReserveRemove.mock.t.Fatalf("Default expectation is already set for the StockRepository.StockReserveRemove method") + } + + if len(mmStockReserveRemove.expectations) > 0 { + mmStockReserveRemove.mock.t.Fatalf("Some expectations are already set for the StockRepository.StockReserveRemove method") + } + + mmStockReserveRemove.mock.funcStockReserveRemove = f + mmStockReserveRemove.mock.funcStockReserveRemoveOrigin = minimock.CallerInfo(1) + return mmStockReserveRemove.mock +} + +// When sets expectation for the StockRepository.StockReserveRemove which will trigger the result defined by the following +// Then helper +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) When(ctx context.Context, stock *entity.Stock) *StockRepositoryMockStockReserveRemoveExpectation { + if mmStockReserveRemove.mock.funcStockReserveRemove != nil { + mmStockReserveRemove.mock.t.Fatalf("StockRepositoryMock.StockReserveRemove mock is already set by Set") + } + + expectation := &StockRepositoryMockStockReserveRemoveExpectation{ + mock: mmStockReserveRemove.mock, + params: &StockRepositoryMockStockReserveRemoveParams{ctx, stock}, + expectationOrigins: StockRepositoryMockStockReserveRemoveExpectationOrigins{origin: minimock.CallerInfo(1)}, + } + mmStockReserveRemove.expectations = append(mmStockReserveRemove.expectations, expectation) + return expectation +} + +// Then sets up StockRepository.StockReserveRemove return parameters for the expectation previously defined by the When method +func (e *StockRepositoryMockStockReserveRemoveExpectation) Then(err error) *StockRepositoryMock { + e.results = &StockRepositoryMockStockReserveRemoveResults{err} + return e.mock +} + +// Times sets number of times StockRepository.StockReserveRemove should be invoked +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Times(n uint64) *mStockRepositoryMockStockReserveRemove { + if n == 0 { + mmStockReserveRemove.mock.t.Fatalf("Times of StockRepositoryMock.StockReserveRemove mock can not be zero") + } + mm_atomic.StoreUint64(&mmStockReserveRemove.expectedInvocations, n) + mmStockReserveRemove.expectedInvocationsOrigin = minimock.CallerInfo(1) + return mmStockReserveRemove +} + +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) invocationsDone() bool { + if len(mmStockReserveRemove.expectations) == 0 && mmStockReserveRemove.defaultExpectation == nil && mmStockReserveRemove.mock.funcStockReserveRemove == nil { + return true + } + + totalInvocations := mm_atomic.LoadUint64(&mmStockReserveRemove.mock.afterStockReserveRemoveCounter) + expectedInvocations := mm_atomic.LoadUint64(&mmStockReserveRemove.expectedInvocations) + + return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations) +} + +// StockReserveRemove implements mm_service.StockRepository +func (mmStockReserveRemove *StockRepositoryMock) StockReserveRemove(ctx context.Context, stock *entity.Stock) (err error) { + mm_atomic.AddUint64(&mmStockReserveRemove.beforeStockReserveRemoveCounter, 1) + defer mm_atomic.AddUint64(&mmStockReserveRemove.afterStockReserveRemoveCounter, 1) + + mmStockReserveRemove.t.Helper() + + if mmStockReserveRemove.inspectFuncStockReserveRemove != nil { + mmStockReserveRemove.inspectFuncStockReserveRemove(ctx, stock) + } + + mm_params := StockRepositoryMockStockReserveRemoveParams{ctx, stock} + + // Record call args + mmStockReserveRemove.StockReserveRemoveMock.mutex.Lock() + mmStockReserveRemove.StockReserveRemoveMock.callArgs = append(mmStockReserveRemove.StockReserveRemoveMock.callArgs, &mm_params) + mmStockReserveRemove.StockReserveRemoveMock.mutex.Unlock() + + for _, e := range mmStockReserveRemove.StockReserveRemoveMock.expectations { + if minimock.Equal(*e.params, mm_params) { + mm_atomic.AddUint64(&e.Counter, 1) + return e.results.err + } + } + + if mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation != nil { + mm_atomic.AddUint64(&mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.Counter, 1) + mm_want := mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.params + mm_want_ptrs := mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.paramPtrs + + mm_got := StockRepositoryMockStockReserveRemoveParams{ctx, stock} + + if mm_want_ptrs != nil { + + if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) { + mmStockReserveRemove.t.Errorf("StockRepositoryMock.StockReserveRemove got unexpected parameter ctx, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.expectationOrigins.originCtx, *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx)) + } + + if mm_want_ptrs.stock != nil && !minimock.Equal(*mm_want_ptrs.stock, mm_got.stock) { + mmStockReserveRemove.t.Errorf("StockRepositoryMock.StockReserveRemove got unexpected parameter stock, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.expectationOrigins.originStock, *mm_want_ptrs.stock, mm_got.stock, minimock.Diff(*mm_want_ptrs.stock, mm_got.stock)) + } + + } else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) { + mmStockReserveRemove.t.Errorf("StockRepositoryMock.StockReserveRemove got unexpected parameters, expected at\n%s:\nwant: %#v\n got: %#v%s\n", + mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.expectationOrigins.origin, *mm_want, mm_got, minimock.Diff(*mm_want, mm_got)) + } + + mm_results := mmStockReserveRemove.StockReserveRemoveMock.defaultExpectation.results + if mm_results == nil { + mmStockReserveRemove.t.Fatal("No results are set for the StockRepositoryMock.StockReserveRemove") + } + return (*mm_results).err + } + if mmStockReserveRemove.funcStockReserveRemove != nil { + return mmStockReserveRemove.funcStockReserveRemove(ctx, stock) + } + mmStockReserveRemove.t.Fatalf("Unexpected call to StockRepositoryMock.StockReserveRemove. %v %v", ctx, stock) + return +} + +// StockReserveRemoveAfterCounter returns a count of finished StockRepositoryMock.StockReserveRemove invocations +func (mmStockReserveRemove *StockRepositoryMock) StockReserveRemoveAfterCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockReserveRemove.afterStockReserveRemoveCounter) +} + +// StockReserveRemoveBeforeCounter returns a count of StockRepositoryMock.StockReserveRemove invocations +func (mmStockReserveRemove *StockRepositoryMock) StockReserveRemoveBeforeCounter() uint64 { + return mm_atomic.LoadUint64(&mmStockReserveRemove.beforeStockReserveRemoveCounter) +} + +// Calls returns a list of arguments used in each call to StockRepositoryMock.StockReserveRemove. +// The list is in the same order as the calls were made (i.e. recent calls have a higher index) +func (mmStockReserveRemove *mStockRepositoryMockStockReserveRemove) Calls() []*StockRepositoryMockStockReserveRemoveParams { + mmStockReserveRemove.mutex.RLock() + + argCopy := make([]*StockRepositoryMockStockReserveRemoveParams, len(mmStockReserveRemove.callArgs)) + copy(argCopy, mmStockReserveRemove.callArgs) + + mmStockReserveRemove.mutex.RUnlock() + + return argCopy +} + +// MinimockStockReserveRemoveDone returns true if the count of the StockReserveRemove invocations corresponds +// the number of defined expectations +func (m *StockRepositoryMock) MinimockStockReserveRemoveDone() bool { + if m.StockReserveRemoveMock.optional { + // Optional methods provide '0 or more' call count restriction. + return true + } + + for _, e := range m.StockReserveRemoveMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + return false + } + } + + return m.StockReserveRemoveMock.invocationsDone() +} + +// MinimockStockReserveRemoveInspect logs each unmet expectation +func (m *StockRepositoryMock) MinimockStockReserveRemoveInspect() { + for _, e := range m.StockReserveRemoveMock.expectations { + if mm_atomic.LoadUint64(&e.Counter) < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserveRemove at\n%s with params: %#v", e.expectationOrigins.origin, *e.params) + } + } + + afterStockReserveRemoveCounter := mm_atomic.LoadUint64(&m.afterStockReserveRemoveCounter) + // if default expectation was set then invocations count should be greater than zero + if m.StockReserveRemoveMock.defaultExpectation != nil && afterStockReserveRemoveCounter < 1 { + if m.StockReserveRemoveMock.defaultExpectation.params == nil { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserveRemove at\n%s", m.StockReserveRemoveMock.defaultExpectation.returnOrigin) + } else { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserveRemove at\n%s with params: %#v", m.StockReserveRemoveMock.defaultExpectation.expectationOrigins.origin, *m.StockReserveRemoveMock.defaultExpectation.params) + } + } + // if func was set then invocations count should be greater than zero + if m.funcStockReserveRemove != nil && afterStockReserveRemoveCounter < 1 { + m.t.Errorf("Expected call to StockRepositoryMock.StockReserveRemove at\n%s", m.funcStockReserveRemoveOrigin) + } + + if !m.StockReserveRemoveMock.invocationsDone() && afterStockReserveRemoveCounter > 0 { + m.t.Errorf("Expected %d calls to StockRepositoryMock.StockReserveRemove at\n%s but found %d calls", + mm_atomic.LoadUint64(&m.StockReserveRemoveMock.expectedInvocations), m.StockReserveRemoveMock.expectedInvocationsOrigin, afterStockReserveRemoveCounter) + } +} + +// MinimockFinish checks that all mocked methods have been called the expected number of times +func (m *StockRepositoryMock) MinimockFinish() { + m.finishOnce.Do(func() { + if !m.minimockDone() { + m.MinimockStockCancelInspect() + + m.MinimockStockGetByIDInspect() + + m.MinimockStockReserveInspect() + + m.MinimockStockReserveRemoveInspect() + } + }) +} + +// MinimockWait waits for all mocked methods to be called the expected number of times +func (m *StockRepositoryMock) MinimockWait(timeout mm_time.Duration) { + timeoutCh := mm_time.After(timeout) + for { + if m.minimockDone() { + return + } + select { + case <-timeoutCh: + m.MinimockFinish() + return + case <-mm_time.After(10 * mm_time.Millisecond): + } + } +} + +func (m *StockRepositoryMock) minimockDone() bool { + done := true + return done && + m.MinimockStockCancelDone() && + m.MinimockStockGetByIDDone() && + m.MinimockStockReserveDone() && + m.MinimockStockReserveRemoveDone() +} diff --git a/loms/internal/domain/service/service.go b/loms/internal/domain/service/service.go new file mode 100644 index 0000000..b579e69 --- /dev/null +++ b/loms/internal/domain/service/service.go @@ -0,0 +1,186 @@ +package service + +import ( + "context" + "fmt" + "slices" + + "route256/loms/internal/domain/entity" + "route256/loms/internal/domain/model" + + pb "route256/pkg/api/loms/v1" + + "github.com/rs/zerolog/log" +) + +//go:generate minimock -i OrderRepository -o ./mock -s _mock.go +type OrderRepository interface { + OrderCreate(ctx context.Context, order *entity.Order) (entity.ID, error) + OrderSetStatus(ctx context.Context, orderID entity.ID, newStatus string) error + OrderGetByID(ctx context.Context, orderID entity.ID) (*entity.Order, error) +} + +//go:generate minimock -i StockRepository -o ./mock -s _mock.go +type StockRepository interface { + StockReserve(ctx context.Context, stock *entity.Stock) error + StockReserveRemove(ctx context.Context, stock *entity.Stock) error + StockCancel(ctx context.Context, stock *entity.Stock) error + StockGetByID(ctx context.Context, sku entity.Sku) (*entity.Stock, error) +} + +type LomsService struct { + orders OrderRepository + stocks StockRepository +} + +func NewLomsService(orderRepo OrderRepository, stockRepo StockRepository) *LomsService { + return &LomsService{ + orders: orderRepo, + stocks: stockRepo, + } +} + +func (s *LomsService) rollbackStocks(ctx context.Context, stocks []*entity.Stock) { + for _, stock := range stocks { + if err := s.stocks.StockCancel(ctx, stock); err != nil { + log.Error().Err(err).Msg("failed to rollback stock") + } + } +} + +func (s *LomsService) OrderCreate(ctx context.Context, orderReq *pb.OrderCreateRequest) (entity.ID, error) { + if orderReq == nil || orderReq.UserId <= 0 || len(orderReq.Items) == 0 { + return 0, model.ErrInvalidInput + } + + for _, item := range orderReq.Items { + if item.Sku <= 0 || item.Count == 0 { + return 0, model.ErrInvalidInput + } + } + + order := &entity.Order{ + OrderID: 0, + Status: pb.OrderStatus_ORDER_STATUS_NEW.String(), + UserID: entity.ID(orderReq.UserId), + Items: make([]entity.OrderItem, len(orderReq.Items)), + } + + for i, item := range orderReq.Items { + order.Items[i] = entity.OrderItem{ + ID: entity.Sku(item.Sku), + Count: item.Count, + } + } + + slices.SortStableFunc(order.Items, func(a, b entity.OrderItem) int { + return int(a.ID - b.ID) + }) + + id, err := s.orders.OrderCreate(ctx, order) + if err != nil { + return 0, fmt.Errorf("orders.OrderCreate: %w", err) + } + + order.OrderID = id + + commitedStocks := make([]*entity.Stock, 0, len(order.Items)) + for _, item := range order.Items { + stock := &entity.Stock{ + Item: item, + Reserved: item.Count, + } + + if err := s.stocks.StockReserve(ctx, stock); err != nil { + s.rollbackStocks(ctx, commitedStocks) + + if statusErr := s.orders.OrderSetStatus(ctx, order.OrderID, pb.OrderStatus_ORDER_STATUS_FAILED.String()); statusErr != nil { + log.Error().Err(statusErr).Msg("failed to update status on stock reserve fail") + } + + return 0, fmt.Errorf("stocks.StockReserve: %w", err) + } + + commitedStocks = append(commitedStocks, stock) + } + + if err := s.orders.OrderSetStatus(ctx, order.OrderID, pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String()); err != nil { + s.rollbackStocks(ctx, commitedStocks) + + return 0, err + } + + return order.OrderID, nil +} + +func (s *LomsService) OrderInfo(ctx context.Context, orderID entity.ID) (*entity.Order, error) { + if orderID <= 0 { + return nil, model.ErrInvalidInput + } + + return s.orders.OrderGetByID(ctx, orderID) +} + +func (s *LomsService) OrderPay(ctx context.Context, orderID entity.ID) error { + order, err := s.OrderInfo(ctx, orderID) + if err != nil { + return err + } + + switch order.Status { + case pb.OrderStatus_ORDER_STATUS_PAYED.String(): + return nil + case pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String(): + for _, item := range order.Items { + if err := s.stocks.StockReserveRemove(ctx, &entity.Stock{ + Item: item, + Reserved: item.Count, + }); err != nil { + log.Error().Err(err).Msg("failed to free stock reservation") + } + } + + return s.orders.OrderSetStatus(ctx, orderID, pb.OrderStatus_ORDER_STATUS_PAYED.String()) + default: + return model.ErrOrderInvalidStatus + } +} + +func (s *LomsService) OrderCancel(ctx context.Context, orderID entity.ID) error { + order, err := s.OrderInfo(ctx, orderID) + if err != nil { + return err + } + + switch order.Status { + case pb.OrderStatus_ORDER_STATUS_CANCELLED.String(): + return nil + case pb.OrderStatus_ORDER_STATUS_FAILED.String(), pb.OrderStatus_ORDER_STATUS_PAYED.String(): + return model.ErrOrderInvalidStatus + } + + stocks := make([]*entity.Stock, len(order.Items)) + for i, item := range order.Items { + stocks[i] = &entity.Stock{ + Item: item, + Reserved: item.Count, + } + } + + s.rollbackStocks(ctx, stocks) + + return s.orders.OrderSetStatus(ctx, orderID, pb.OrderStatus_ORDER_STATUS_CANCELLED.String()) +} + +func (s *LomsService) StocksInfo(ctx context.Context, sku entity.Sku) (uint32, error) { + if sku <= 0 { + return 0, model.ErrInvalidInput + } + + stock, err := s.stocks.StockGetByID(ctx, sku) + if err != nil { + return 0, err + } + + return stock.Item.Count, nil +} diff --git a/loms/internal/domain/service/service_test.go b/loms/internal/domain/service/service_test.go new file mode 100644 index 0000000..c5af63f --- /dev/null +++ b/loms/internal/domain/service/service_test.go @@ -0,0 +1,448 @@ +package service + +import ( + "context" + "errors" + "testing" + + "github.com/gojuno/minimock/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "route256/loms/internal/domain/entity" + "route256/loms/internal/domain/model" + mock "route256/loms/internal/domain/service/mock" + + pb "route256/pkg/api/loms/v1" +) + +const ( + testUser = entity.ID(1337) + testSku = entity.Sku(199) +) + +func TestLomsService_OrderCreate(t *testing.T) { + t.Parallel() + + ctx := context.Background() + mc := minimock.NewController(t) + + goodReq := &pb.OrderCreateRequest{ + UserId: int64(testUser), + Items: []*pb.OrderItem{ + { + Sku: int64(testSku), + Count: 2, + }, + }, + } + + badItemReq := &pb.OrderCreateRequest{ + UserId: int64(testUser), + Items: []*pb.OrderItem{ + { + Sku: 0, + Count: 0, + }, + }, + } + + type fields struct { + orders OrderRepository + stocks StockRepository + } + type args struct { + req *pb.OrderCreateRequest + } + + tests := []struct { + name string + fields fields + args args + wantErr require.ErrorAssertionFunc + }{ + { + name: "success", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderCreateMock.Return(1, nil). + OrderSetStatusMock.Return(nil), + stocks: mock.NewStockRepositoryMock(mc). + StockReserveMock.Return(nil), + }, + args: args{ + req: goodReq, + }, + wantErr: require.NoError, + }, + { + name: "invalid input", + fields: fields{}, + args: args{ + req: &pb.OrderCreateRequest{ + UserId: 0, + }, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrInvalidInput) + }, + }, + { + name: "invalid input with bad items", + fields: fields{}, + args: args{ + req: badItemReq, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrInvalidInput) + }, + }, + { + name: "order create error", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderCreateMock.Return(0, errors.New("order create error")), + stocks: nil, + }, + args: args{ + req: goodReq, + }, + wantErr: require.Error, + }, + { + name: "stock reserve error", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderCreateMock.Return(1, nil). + OrderSetStatusMock.Return(errors.New("status update error")), + stocks: mock.NewStockRepositoryMock(mc). + StockReserveMock.Return(errors.New("reservation error")), + }, + args: args{ + req: goodReq, + }, + wantErr: require.Error, + }, + { + name: "final status update error", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderCreateMock.Return(1, nil). + OrderSetStatusMock.Return(errors.New("unexpected error")), + stocks: mock.NewStockRepositoryMock(mc). + StockReserveMock.Return(nil). + StockCancelMock.Return(nil), + }, + args: args{ + req: goodReq, + }, + wantErr: require.Error, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + svc := NewLomsService(tt.fields.orders, tt.fields.stocks) + _, err := svc.OrderCreate(ctx, tt.args.req) + tt.wantErr(t, err) + }) + } +} + +func TestLomsService_OrderPay(t *testing.T) { + t.Parallel() + + ctx := context.Background() + mc := minimock.NewController(t) + + awaitingOrder := &entity.Order{ + OrderID: 1, + Status: pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String(), + Items: []entity.OrderItem{{ + ID: testSku, + Count: 2, + }}, + } + + payedOrder := &entity.Order{OrderID: 2, Status: pb.OrderStatus_ORDER_STATUS_PAYED.String()} + badStatusOrder := &entity.Order{OrderID: 3, Status: pb.OrderStatus_ORDER_STATUS_FAILED.String()} + + type fields struct { + orders OrderRepository + stocks StockRepository + } + type args struct { + id entity.ID + } + + tests := []struct { + name string + fields fields + args args + wantErr require.ErrorAssertionFunc + }{ + { + name: "success", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(awaitingOrder, nil). + OrderSetStatusMock.Return(nil), + stocks: mock.NewStockRepositoryMock(mc). + StockReserveRemoveMock.Return(nil), + }, + args: args{ + id: awaitingOrder.OrderID, + }, + wantErr: require.NoError, + }, + { + name: "invalid input", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc), + stocks: mock.NewStockRepositoryMock(mc), + }, + args: args{ + id: 0, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrInvalidInput) + }, + }, + { + name: "already payed", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(payedOrder, nil), + }, + args: args{ + id: payedOrder.OrderID, + }, + wantErr: require.NoError, + }, + { + name: "invalid status", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(badStatusOrder, nil), + }, + args: args{ + id: badStatusOrder.OrderID, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrOrderInvalidStatus) + }, + }, + { + name: "unexpected logged error on updating stocks reserves", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(awaitingOrder, nil). + OrderSetStatusMock.Return(nil), + stocks: mock.NewStockRepositoryMock(mc). + StockReserveRemoveMock.Return(errors.New("unexpected error")), + }, + args: args{ + id: badStatusOrder.OrderID, + }, + wantErr: require.NoError, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + svc := NewLomsService(tt.fields.orders, tt.fields.stocks) + err := svc.OrderPay(ctx, tt.args.id) + tt.wantErr(t, err) + }) + } +} + +func TestLomsService_OrderInfo(t *testing.T) { + t.Parallel() + + mc := minimock.NewController(t) + svc := NewLomsService( + mock.NewOrderRepositoryMock(mc), + mock.NewStockRepositoryMock(mc), + ) + + err := svc.OrderPay(context.Background(), 0) + require.ErrorIs(t, err, model.ErrInvalidInput) +} + +func TestLomsService_OrderCancel(t *testing.T) { + t.Parallel() + + ctx := context.Background() + mc := minimock.NewController(t) + + awaiting := &entity.Order{ + OrderID: 1, + Status: pb.OrderStatus_ORDER_STATUS_AWAITING_PAYMENT.String(), + Items: []entity.OrderItem{{ + ID: testSku, Count: 1, + }}, + } + cancelled := &entity.Order{ + OrderID: 2, + Status: pb.OrderStatus_ORDER_STATUS_CANCELLED.String(), + } + payed := &entity.Order{ + OrderID: 3, + Status: pb.OrderStatus_ORDER_STATUS_PAYED.String(), + } + + type fields struct { + orders OrderRepository + stocks StockRepository + } + type args struct { + id entity.ID + } + + tests := []struct { + name string + fields fields + args args + wantErr require.ErrorAssertionFunc + }{ + { + name: "success", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(awaiting, nil). + OrderSetStatusMock.Return(nil), + stocks: mock.NewStockRepositoryMock(mc). + StockCancelMock.Return(nil), + }, + args: args{ + id: awaiting.OrderID, + }, + wantErr: require.NoError, + }, + { + name: "invalid input", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc), + stocks: mock.NewStockRepositoryMock(mc), + }, + args: args{ + id: 0, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrInvalidInput) + }, + }, + { + name: "already cancelled", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(cancelled, nil), + }, + args: args{ + id: cancelled.OrderID, + }, + wantErr: require.NoError, + }, + { + name: "invalid status", + fields: fields{ + orders: mock.NewOrderRepositoryMock(mc). + OrderGetByIDMock.Return(payed, nil), + }, + args: args{ + id: payed.OrderID, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrOrderInvalidStatus) + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + svc := NewLomsService(tt.fields.orders, tt.fields.stocks) + err := svc.OrderCancel(ctx, tt.args.id) + tt.wantErr(t, err) + }) + } +} + +func TestLomsService_StocksInfo(t *testing.T) { + t.Parallel() + + ctx := context.Background() + mc := minimock.NewController(t) + + type fields struct{ stocks StockRepository } + type args struct{ sku entity.Sku } + + tests := []struct { + name string + fields fields + args args + want uint32 + wantErr require.ErrorAssertionFunc + }{ + { + name: "success", + fields: fields{ + stocks: mock.NewStockRepositoryMock(mc). + StockGetByIDMock.Return(&entity.Stock{ + Item: entity.OrderItem{ + Count: 7, + }, + }, nil), + }, + args: args{ + sku: testSku, + }, + want: 7, + wantErr: require.NoError, + }, + { + name: "invalid sku", + fields: fields{}, + args: args{ + sku: 0, + }, + wantErr: func(t require.TestingT, err error, _ ...interface{}) { + require.ErrorIs(t, err, model.ErrInvalidInput) + }, + }, + { + name: "get by id error", + fields: fields{ + stocks: mock.NewStockRepositoryMock(mc). + StockGetByIDMock.Return(nil, errors.New("unexpected error")), + }, + args: args{ + sku: testSku, + }, + wantErr: require.Error, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + svc := NewLomsService(nil, tt.fields.stocks) + got, err := svc.StocksInfo(ctx, tt.args.sku) + tt.wantErr(t, err) + if err == nil { + assert.Equal(t, tt.want, got) + } + }) + } +} diff --git a/loms/internal/infra/config/config.go b/loms/internal/infra/config/config.go new file mode 100644 index 0000000..dfb32e3 --- /dev/null +++ b/loms/internal/infra/config/config.go @@ -0,0 +1,74 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "gopkg.in/yaml.v3" +) + +type Config struct { + Service struct { + Host string `yaml:"host"` + GRPCPort string `yaml:"grpc_port"` + HTTPPort string `yaml:"http_port"` + LogLevel string `yaml:"log_level"` + } `yaml:"service"` + + Jaeger struct { + Host string `yaml:"host"` + Port string `yaml:"port"` + } `yaml:"jaeger"` + + DatabaseMaster struct { + Host string `yaml:"host"` + Port string `yaml:"port"` + User string `yaml:"user"` + Password string `yaml:"password"` + DBName string `yaml:"db_name"` + } `yaml:"db_master"` + + DatabaseReplica struct { + Host string `yaml:"host"` + Port string `yaml:"port"` + User string `yaml:"user"` + Password string `yaml:"password"` + DBName string `yaml:"db_name"` + } `yaml:"db_replica"` + + Kafka struct { + Host string `yaml:"host"` + Port string `yaml:"port"` + OrderTopic string `yaml:"order_topic"` + Brokers string `yaml:"brokers"` + } `yaml:"kafka"` +} + +func LoadConfig(filename string) (*Config, error) { + workDir, err := os.Getwd() + if err != nil { + return nil, err + } + cfgRoot := filepath.Join(workDir, "configs") + absCfgRoot, _ := filepath.Abs(cfgRoot) + + filePath := filepath.Join(absCfgRoot, filepath.Clean(filename)) + if !strings.HasPrefix(filePath, absCfgRoot) { + return nil, fmt.Errorf("invalid path") + } + + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer f.Close() + + config := &Config{} + if err := yaml.NewDecoder(f).Decode(config); err != nil { + return nil, err + } + + return config, nil +} diff --git a/loms/internal/infra/grpc/middleware/logging.go b/loms/internal/infra/grpc/middleware/logging.go new file mode 100644 index 0000000..23da530 --- /dev/null +++ b/loms/internal/infra/grpc/middleware/logging.go @@ -0,0 +1,24 @@ +package mw + +import ( + "context" + + "github.com/rs/zerolog/log" + "google.golang.org/grpc" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" +) + +func Logging(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + raw, _ := protojson.Marshal((req).(proto.Message)) + log.Debug().Msgf("request: method: %v, req: %s", info.FullMethod, string(raw)) + + if resp, err = handler(ctx, req); err != nil { + log.Debug().Msgf("response: method: %v, err: %s", info.FullMethod, err.Error()) + return + } + rawResp, _ := protojson.Marshal((resp).(proto.Message)) + log.Debug().Msgf("response: method: %v, resp: %s", info.FullMethod, string(rawResp)) + + return +} diff --git a/loms/internal/infra/grpc/middleware/validate.go b/loms/internal/infra/grpc/middleware/validate.go new file mode 100644 index 0000000..9aad15a --- /dev/null +++ b/loms/internal/infra/grpc/middleware/validate.go @@ -0,0 +1,18 @@ +package mw + +import ( + "context" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func Validate(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { + if v, ok := req.(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + } + return handler(ctx, req) +} diff --git a/loms/tests/integration/loms_integration_test.go b/loms/tests/integration/loms_integration_test.go new file mode 100644 index 0000000..8109044 --- /dev/null +++ b/loms/tests/integration/loms_integration_test.go @@ -0,0 +1,130 @@ +//go:build integration +// +build integration + +package integration + +import ( + "context" + "net" + "testing" + "time" + + "github.com/ozontech/allure-go/pkg/framework/provider" + "github.com/ozontech/allure-go/pkg/framework/suite" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "route256/loms/internal/app/server" + "route256/loms/internal/domain/entity" + ordersRepository "route256/loms/internal/domain/repository/orders" + stocksRepository "route256/loms/internal/domain/repository/stocks" + lomsService "route256/loms/internal/domain/service" + + pb "route256/pkg/api/loms/v1" +) + +const ( + // "total_count": 100, + // "reserved": 35 + testSKU = entity.Sku(1076963) + + testUID = entity.ID(1337) + testCount = uint32(2) +) + +type LomsIntegrationSuite struct { + suite.Suite + + grpcSrv *grpc.Server + grpcConn *grpc.ClientConn + lomsClient pb.LOMSClient +} + +func TestLomsIntegrationSuite(t *testing.T) { + suite.RunSuite(t, new(LomsIntegrationSuite)) +} + +func (s *LomsIntegrationSuite) BeforeAll(t provider.T) { + t.WithNewStep("init cart-service", func(sCtx provider.StepCtx) { + orderRepo := ordersRepository.NewInMemoryRepository(100) + stockRepo, err := stocksRepository.NewInMemoryRepository(100) + sCtx.Require().NoError(err) + + svc := lomsService.NewLomsService(orderRepo, stockRepo) + lomsServer := server.NewServer(svc) + + lis, err := net.Listen("tcp", "127.0.0.1:0") + sCtx.Require().NoError(err) + + s.grpcSrv = grpc.NewServer() + pb.RegisterLOMSServer(s.grpcSrv, lomsServer) + + go func() { _ = s.grpcSrv.Serve(lis) }() + + time.Sleep(50 * time.Millisecond) + + conn, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()) + sCtx.Require().NoError(err) + + s.grpcConn = conn + s.lomsClient = pb.NewLOMSClient(conn) + }) +} + +func (s *LomsIntegrationSuite) AfterAll(t provider.T) { + s.grpcSrv.Stop() + _ = s.grpcConn.Close() +} + +func (s *LomsIntegrationSuite) TestOrderProcessPositive(t provider.T) { + ctx := context.Background() + + var orderID int64 + + t.WithNewStep("create order", func(sCtx provider.StepCtx) { + req := &pb.OrderCreateRequest{ + UserId: int64(testUID), + Items: []*pb.OrderItem{{ + Sku: int64(testSKU), + Count: testCount, + }}, + } + + resp, err := s.lomsClient.OrderCreate(ctx, req) + sCtx.Require().NoError(err) + sCtx.Require().Greater(resp.OrderId, int64(0)) + orderID = resp.OrderId + }) + + t.WithNewStep("verify order info (NEW)", func(sCtx provider.StepCtx) { + resp, err := s.lomsClient.OrderInfo(ctx, &pb.OrderInfoRequest{OrderId: orderID}) + sCtx.Require().NoError(err) + + sCtx.Require().Equal("awaiting payment", resp.Status) + sCtx.Require().Equal(int64(testUID), resp.UserId) + sCtx.Require().Len(resp.Items, 1) + sCtx.Require().Equal(int64(testSKU), resp.Items[0].Sku) + sCtx.Require().Equal(testCount, resp.Items[0].Count) + }) + + t.WithNewStep("pay order", func(sCtx provider.StepCtx) { + _, err := s.lomsClient.OrderPay(ctx, &pb.OrderPayRequest{OrderId: orderID}) + sCtx.Require().NoError(err) + }) + + t.WithNewStep("verify order info (PAYED)", func(sCtx provider.StepCtx) { + resp, err := s.lomsClient.OrderInfo(ctx, &pb.OrderInfoRequest{OrderId: orderID}) + sCtx.Require().NoError(err) + sCtx.Require().Equal("payed", resp.Status) + }) +} + +func (s *LomsIntegrationSuite) TestStocksInfoPositive(t provider.T) { + ctx := context.Background() + + t.WithNewStep("call StocksInfo", func(sCtx provider.StepCtx) { + resp, err := s.lomsClient.StocksInfo(ctx, &pb.StocksInfoRequest{Sku: int64(testSKU)}) + sCtx.Require().NoError(err) + sCtx.Require().Greater(resp.Count, uint32(0)) + }) +} diff --git a/make/generate.mk b/make/generate.mk index aae174a..8961c77 100644 --- a/make/generate.mk +++ b/make/generate.mk @@ -1,4 +1,66 @@ +CURDIR=$(shell pwd) +BINDIR=${CURDIR}/bin +.PHONY: .bin-deps +.bin-deps: + $(info Installing binary dependencies...) + + GOBIN=$(BINDIR) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 && \ + GOBIN=$(BINDIR) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 && \ + GOBIN=$(BINDIR) go install github.com/envoyproxy/protoc-gen-validate@v1.0.4 && \ + GOBIN=$(BINDIR) go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.19.1 && \ + GOBIN=$(BINDIR) go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.19.1 && \ + GOBIN=$(BINDIR) go install github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 + +# Устанавливаем proto описания google/protobuf +vendor-proto/google/protobuf: + git clone -b main --single-branch -n --depth=1 \ + https://github.com/protocolbuffers/protobuf vendor-proto/protobuf &&\ + cd vendor-proto/protobuf &&\ + git sparse-checkout set --no-cone src/google/protobuf &&\ + git checkout + mkdir -p vendor-proto/google + mv vendor-proto/protobuf/src/google/protobuf vendor-proto/google + rm -rf vendor-proto/protobuf + +# Устанавливаем proto описания validate +vendor-proto/validate: + git clone -b main --single-branch --depth=2 \ + https://github.com/bufbuild/protoc-gen-validate vendor-proto/tmp && \ + cd vendor-proto/tmp && \ + git sparse-checkout set --no-cone validate &&\ + git checkout + mkdir -p vendor-proto/validate + mv vendor-proto/tmp/validate vendor-proto/ + rm -rf vendor-proto/tmp + +# Устанавливаем proto описания google/googleapis +vendor-proto/google/api: + git clone -b master --single-branch -n --depth=1 \ + https://github.com/googleapis/googleapis vendor-proto/googleapis && \ + cd vendor-proto/googleapis && \ + git sparse-checkout set --no-cone google/api && \ + git checkout + mkdir -p vendor-proto/google + mv vendor-proto/googleapis/google/api vendor-proto/google + rm -rf vendor-proto/googleapis + +# Устанавливаем proto описания protoc-gen-openapiv2/options +vendor-proto/protoc-gen-openapiv2/options: + git clone -b main --single-branch -n --depth=1 \ + https://github.com/grpc-ecosystem/grpc-gateway vendor-proto/grpc-ecosystem && \ + cd vendor-proto/grpc-ecosystem && \ + git sparse-checkout set --no-cone protoc-gen-openapiv2/options && \ + git checkout + mkdir -p vendor-proto/protoc-gen-openapiv2 + mv vendor-proto/grpc-ecosystem/protoc-gen-openapiv2/options vendor-proto/protoc-gen-openapiv2 + rm -rf vendor-proto/grpc-ecosystem + +.PHONY: .vendor-rm +.vendor-rm: + rm -rf vendor-proto + +.vendor-proto: .vendor-rm vendor-proto/google/protobuf vendor-proto/validate vendor-proto/google/api vendor-proto/protoc-gen-openapiv2/options define generate @if [ -f "$(1)/go.mod" ]; then \ @@ -11,12 +73,35 @@ define generate fi endef +define proto_gen + @echo "== generating $(1) ==" + @protoc \ + -I api \ + -I vendor-proto \ + --plugin=protoc-gen-go=$(BINDIR)/protoc-gen-go \ + --go_out=pkg/api/ --go_opt paths=source_relative \ + --plugin=protoc-gen-go-grpc=$(BINDIR)/protoc-gen-go-grpc \ + --go-grpc_out=pkg/api/ --go-grpc_opt paths=source_relative \ + --plugin=protoc-gen-validate=$(BINDIR)/protoc-gen-validate \ + --validate_out="lang=go,paths=source_relative:pkg/api/" \ + --plugin=protoc-gen-grpc-gateway=$(BINDIR)/protoc-gen-grpc-gateway \ + --grpc-gateway_out=pkg/api/ \ + --grpc-gateway_opt=logtostderr=true,paths=source_relative,generate_unbound_methods=true \ + --plugin=protoc-gen-openapiv2=$(BINDIR)/protoc-gen-openapiv2 \ + --openapiv2_out=api/openapiv2 \ + --openapiv2_opt=logtostderr=true \ + $(1) +endef cart-generate: $(call generate,cart) + cd cart && go mod tidy loms-generate: $(call generate,loms) + mkdir -p "api/openapiv2" + $(foreach f,$(shell find api/loms/v1 -type f -name '*.proto'),$(call proto_gen,$(f),loms)) + cd loms && go mod tidy notifier-generate: $(call generate,notifier) diff --git a/pkg/api/loms/v1/loms.pb.go b/pkg/api/loms/v1/loms.pb.go new file mode 100644 index 0000000..ba164c2 --- /dev/null +++ b/pkg/api/loms/v1/loms.pb.go @@ -0,0 +1,827 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v6.30.0 +// source: loms/v1/loms.proto + +package loms + +import ( + _ "github.com/envoyproxy/protoc-gen-validate/validate" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type OrderStatus int32 + +const ( + OrderStatus_ORDER_STATUS_UNSPECIFIED OrderStatus = 0 + OrderStatus_ORDER_STATUS_NEW OrderStatus = 1 + OrderStatus_ORDER_STATUS_AWAITING_PAYMENT OrderStatus = 2 + OrderStatus_ORDER_STATUS_FAILED OrderStatus = 3 + OrderStatus_ORDER_STATUS_PAYED OrderStatus = 4 + OrderStatus_ORDER_STATUS_CANCELLED OrderStatus = 5 +) + +// Enum value maps for OrderStatus. +var ( + OrderStatus_name = map[int32]string{ + 0: "ORDER_STATUS_UNSPECIFIED", + 1: "ORDER_STATUS_NEW", + 2: "ORDER_STATUS_AWAITING_PAYMENT", + 3: "ORDER_STATUS_FAILED", + 4: "ORDER_STATUS_PAYED", + 5: "ORDER_STATUS_CANCELLED", + } + OrderStatus_value = map[string]int32{ + "ORDER_STATUS_UNSPECIFIED": 0, + "ORDER_STATUS_NEW": 1, + "ORDER_STATUS_AWAITING_PAYMENT": 2, + "ORDER_STATUS_FAILED": 3, + "ORDER_STATUS_PAYED": 4, + "ORDER_STATUS_CANCELLED": 5, + } +) + +func (x OrderStatus) Enum() *OrderStatus { + p := new(OrderStatus) + *p = x + return p +} + +func (x OrderStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (OrderStatus) Descriptor() protoreflect.EnumDescriptor { + return file_loms_v1_loms_proto_enumTypes[0].Descriptor() +} + +func (OrderStatus) Type() protoreflect.EnumType { + return &file_loms_v1_loms_proto_enumTypes[0] +} + +func (x OrderStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OrderStatus.Descriptor instead. +func (OrderStatus) EnumDescriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{0} +} + +type OrderItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sku int64 `protobuf:"varint,1,opt,name=sku,proto3" json:"sku,omitempty"` + Count uint32 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` +} + +func (x *OrderItem) Reset() { + *x = OrderItem{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderItem) ProtoMessage() {} + +func (x *OrderItem) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[0] + 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 OrderItem.ProtoReflect.Descriptor instead. +func (*OrderItem) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{0} +} + +func (x *OrderItem) GetSku() int64 { + if x != nil { + return x.Sku + } + return 0 +} + +func (x *OrderItem) GetCount() uint32 { + if x != nil { + return x.Count + } + return 0 +} + +type OrderCreateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Items []*OrderItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *OrderCreateRequest) Reset() { + *x = OrderCreateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderCreateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderCreateRequest) ProtoMessage() {} + +func (x *OrderCreateRequest) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_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 OrderCreateRequest.ProtoReflect.Descriptor instead. +func (*OrderCreateRequest) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{1} +} + +func (x *OrderCreateRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *OrderCreateRequest) GetItems() []*OrderItem { + if x != nil { + return x.Items + } + return nil +} + +type OrderCreateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrderId int64 `protobuf:"varint,1,opt,name=orderId,proto3" json:"orderId,omitempty"` +} + +func (x *OrderCreateResponse) Reset() { + *x = OrderCreateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderCreateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderCreateResponse) ProtoMessage() {} + +func (x *OrderCreateResponse) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[2] + 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 OrderCreateResponse.ProtoReflect.Descriptor instead. +func (*OrderCreateResponse) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{2} +} + +func (x *OrderCreateResponse) GetOrderId() int64 { + if x != nil { + return x.OrderId + } + return 0 +} + +type OrderInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrderId int64 `protobuf:"varint,1,opt,name=orderId,proto3" json:"orderId,omitempty"` +} + +func (x *OrderInfoRequest) Reset() { + *x = OrderInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderInfoRequest) ProtoMessage() {} + +func (x *OrderInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[3] + 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 OrderInfoRequest.ProtoReflect.Descriptor instead. +func (*OrderInfoRequest) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{3} +} + +func (x *OrderInfoRequest) GetOrderId() int64 { + if x != nil { + return x.OrderId + } + return 0 +} + +type OrderInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Items []*OrderItem `protobuf:"bytes,3,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *OrderInfoResponse) Reset() { + *x = OrderInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderInfoResponse) ProtoMessage() {} + +func (x *OrderInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[4] + 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 OrderInfoResponse.ProtoReflect.Descriptor instead. +func (*OrderInfoResponse) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{4} +} + +func (x *OrderInfoResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *OrderInfoResponse) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *OrderInfoResponse) GetItems() []*OrderItem { + if x != nil { + return x.Items + } + return nil +} + +type OrderPayRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrderId int64 `protobuf:"varint,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` +} + +func (x *OrderPayRequest) Reset() { + *x = OrderPayRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderPayRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderPayRequest) ProtoMessage() {} + +func (x *OrderPayRequest) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[5] + 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 OrderPayRequest.ProtoReflect.Descriptor instead. +func (*OrderPayRequest) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{5} +} + +func (x *OrderPayRequest) GetOrderId() int64 { + if x != nil { + return x.OrderId + } + return 0 +} + +type OrderCancelRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrderId int64 `protobuf:"varint,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` +} + +func (x *OrderCancelRequest) Reset() { + *x = OrderCancelRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderCancelRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderCancelRequest) ProtoMessage() {} + +func (x *OrderCancelRequest) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_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 OrderCancelRequest.ProtoReflect.Descriptor instead. +func (*OrderCancelRequest) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{6} +} + +func (x *OrderCancelRequest) GetOrderId() int64 { + if x != nil { + return x.OrderId + } + return 0 +} + +type StocksInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sku int64 `protobuf:"varint,1,opt,name=sku,proto3" json:"sku,omitempty"` +} + +func (x *StocksInfoRequest) Reset() { + *x = StocksInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StocksInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StocksInfoRequest) ProtoMessage() {} + +func (x *StocksInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[7] + 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 StocksInfoRequest.ProtoReflect.Descriptor instead. +func (*StocksInfoRequest) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{7} +} + +func (x *StocksInfoRequest) GetSku() int64 { + if x != nil { + return x.Sku + } + return 0 +} + +type StocksInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Count uint32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` +} + +func (x *StocksInfoResponse) Reset() { + *x = StocksInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_loms_v1_loms_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StocksInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StocksInfoResponse) ProtoMessage() {} + +func (x *StocksInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_loms_v1_loms_proto_msgTypes[8] + 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 StocksInfoResponse.ProtoReflect.Descriptor instead. +func (*StocksInfoResponse) Descriptor() ([]byte, []int) { + return file_loms_v1_loms_proto_rawDescGZIP(), []int{8} +} + +func (x *StocksInfoResponse) GetCount() uint32 { + if x != nil { + return x.Count + } + return 0 +} + +var File_loms_v1_loms_proto protoreflect.FileDescriptor + +var file_loms_v1_loms_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x6c, 0x6f, 0x6d, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6c, 0x6f, 0x6d, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 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, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 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, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x45, 0x0a, 0x09, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x6b, 0x75, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, 0x03, 0x73, 0x6b, 0x75, + 0x12, 0x1d, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0x62, 0x0a, 0x12, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, + 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, + 0x65, 0x6d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x05, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x22, 0x2f, 0x0a, 0x13, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x49, 0x64, 0x22, 0x35, 0x0a, 0x10, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, + 0x20, 0x00, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x22, 0x66, 0x0a, 0x11, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x20, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0a, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x22, 0x35, 0x0a, 0x0f, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x61, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x20, + 0x00, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x22, 0x38, 0x0a, 0x12, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x22, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, 0x07, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x49, 0x64, 0x22, 0x2e, 0x0a, 0x11, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x73, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x73, 0x6b, 0x75, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, + 0x03, 0x73, 0x6b, 0x75, 0x22, 0x2a, 0x0a, 0x12, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x73, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x2a, 0xb1, 0x01, 0x0a, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, + 0x0a, 0x10, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, + 0x45, 0x57, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x41, + 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x4f, 0x52, 0x44, 0x45, 0x52, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x16, 0x0a, 0x12, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x50, 0x41, 0x59, 0x45, 0x44, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x4f, 0x52, 0x44, 0x45, + 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, + 0x45, 0x44, 0x10, 0x05, 0x32, 0xc2, 0x04, 0x0a, 0x04, 0x4c, 0x4f, 0x4d, 0x53, 0x12, 0x52, 0x0a, + 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x14, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, + 0x0d, 0x2f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x3a, 0x01, + 0x2a, 0x12, 0x47, 0x0a, 0x09, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x11, + 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x12, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a, 0x08, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x50, 0x61, 0x79, 0x12, 0x10, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x50, 0x61, + 0x79, 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, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x22, 0x0a, 0x2f, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2f, 0x70, 0x61, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x54, 0x0a, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x13, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, + 0x6e, 0x63, 0x65, 0x6c, 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, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x3a, 0x01, 0x2a, 0x12, 0x4a, 0x0a, + 0x0a, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x2e, 0x53, 0x74, + 0x6f, 0x63, 0x6b, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x13, 0x2e, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x73, + 0x74, 0x6f, 0x63, 0x6b, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0xad, 0x01, 0x92, 0x41, 0xa9, 0x01, + 0x12, 0x0c, 0x4c, 0x4f, 0x4d, 0x53, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x1a, 0x98, + 0x01, 0x0a, 0x20, 0x46, 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x6d, 0x6f, 0x72, 0x65, + 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x12, 0x74, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x65, 0x63, 0x6f, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x62, 0x2f, + 0x61, 0x5f, 0x62, 0x69, 0x74, 0x5f, 0x6f, 0x66, 0x5f, 0x65, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x61, 0x5a, 0x1d, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x32, 0x35, 0x36, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6c, 0x6f, + 0x6d, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x6c, 0x6f, 0x6d, 0x73, 0x92, 0x41, 0x3f, 0x12, 0x15, 0x0a, + 0x0c, 0x4c, 0x4f, 0x4d, 0x53, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0x05, 0x31, + 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_loms_v1_loms_proto_rawDescOnce sync.Once + file_loms_v1_loms_proto_rawDescData = file_loms_v1_loms_proto_rawDesc +) + +func file_loms_v1_loms_proto_rawDescGZIP() []byte { + file_loms_v1_loms_proto_rawDescOnce.Do(func() { + file_loms_v1_loms_proto_rawDescData = protoimpl.X.CompressGZIP(file_loms_v1_loms_proto_rawDescData) + }) + return file_loms_v1_loms_proto_rawDescData +} + +var file_loms_v1_loms_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_loms_v1_loms_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_loms_v1_loms_proto_goTypes = []interface{}{ + (OrderStatus)(0), // 0: OrderStatus + (*OrderItem)(nil), // 1: OrderItem + (*OrderCreateRequest)(nil), // 2: OrderCreateRequest + (*OrderCreateResponse)(nil), // 3: OrderCreateResponse + (*OrderInfoRequest)(nil), // 4: OrderInfoRequest + (*OrderInfoResponse)(nil), // 5: OrderInfoResponse + (*OrderPayRequest)(nil), // 6: OrderPayRequest + (*OrderCancelRequest)(nil), // 7: OrderCancelRequest + (*StocksInfoRequest)(nil), // 8: StocksInfoRequest + (*StocksInfoResponse)(nil), // 9: StocksInfoResponse + (*emptypb.Empty)(nil), // 10: google.protobuf.Empty +} +var file_loms_v1_loms_proto_depIdxs = []int32{ + 1, // 0: OrderCreateRequest.items:type_name -> OrderItem + 1, // 1: OrderInfoResponse.items:type_name -> OrderItem + 2, // 2: LOMS.OrderCreate:input_type -> OrderCreateRequest + 4, // 3: LOMS.OrderInfo:input_type -> OrderInfoRequest + 6, // 4: LOMS.OrderPay:input_type -> OrderPayRequest + 7, // 5: LOMS.OrderCancel:input_type -> OrderCancelRequest + 8, // 6: LOMS.StocksInfo:input_type -> StocksInfoRequest + 3, // 7: LOMS.OrderCreate:output_type -> OrderCreateResponse + 5, // 8: LOMS.OrderInfo:output_type -> OrderInfoResponse + 10, // 9: LOMS.OrderPay:output_type -> google.protobuf.Empty + 10, // 10: LOMS.OrderCancel:output_type -> google.protobuf.Empty + 9, // 11: LOMS.StocksInfo:output_type -> StocksInfoResponse + 7, // [7:12] is the sub-list for method output_type + 2, // [2:7] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_loms_v1_loms_proto_init() } +func file_loms_v1_loms_proto_init() { + if File_loms_v1_loms_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_loms_v1_loms_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderCreateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderCreateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderInfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderInfoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderPayRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderCancelRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StocksInfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_loms_v1_loms_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StocksInfoResponse); 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{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_loms_v1_loms_proto_rawDesc, + NumEnums: 1, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_loms_v1_loms_proto_goTypes, + DependencyIndexes: file_loms_v1_loms_proto_depIdxs, + EnumInfos: file_loms_v1_loms_proto_enumTypes, + MessageInfos: file_loms_v1_loms_proto_msgTypes, + }.Build() + File_loms_v1_loms_proto = out.File + file_loms_v1_loms_proto_rawDesc = nil + file_loms_v1_loms_proto_goTypes = nil + file_loms_v1_loms_proto_depIdxs = nil +} diff --git a/pkg/api/loms/v1/loms.pb.gw.go b/pkg/api/loms/v1/loms.pb.gw.go new file mode 100644 index 0000000..80aacc2 --- /dev/null +++ b/pkg/api/loms/v1/loms.pb.gw.go @@ -0,0 +1,491 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: loms/v1/loms.proto + +/* +Package loms is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package loms + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_LOMS_OrderCreate_0(ctx context.Context, marshaler runtime.Marshaler, client LOMSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderCreateRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.OrderCreate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LOMS_OrderCreate_0(ctx context.Context, marshaler runtime.Marshaler, server LOMSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderCreateRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.OrderCreate(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_LOMS_OrderInfo_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_LOMS_OrderInfo_0(ctx context.Context, marshaler runtime.Marshaler, client LOMSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LOMS_OrderInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.OrderInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LOMS_OrderInfo_0(ctx context.Context, marshaler runtime.Marshaler, server LOMSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LOMS_OrderInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.OrderInfo(ctx, &protoReq) + return msg, metadata, err + +} + +func request_LOMS_OrderPay_0(ctx context.Context, marshaler runtime.Marshaler, client LOMSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderPayRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.OrderPay(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LOMS_OrderPay_0(ctx context.Context, marshaler runtime.Marshaler, server LOMSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderPayRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.OrderPay(ctx, &protoReq) + return msg, metadata, err + +} + +func request_LOMS_OrderCancel_0(ctx context.Context, marshaler runtime.Marshaler, client LOMSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderCancelRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.OrderCancel(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LOMS_OrderCancel_0(ctx context.Context, marshaler runtime.Marshaler, server LOMSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OrderCancelRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.OrderCancel(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_LOMS_StocksInfo_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_LOMS_StocksInfo_0(ctx context.Context, marshaler runtime.Marshaler, client LOMSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StocksInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LOMS_StocksInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.StocksInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LOMS_StocksInfo_0(ctx context.Context, marshaler runtime.Marshaler, server LOMSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StocksInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LOMS_StocksInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.StocksInfo(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterLOMSHandlerServer registers the http handlers for service LOMS to "mux". +// UnaryRPC :call LOMSServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterLOMSHandlerFromEndpoint instead. +func RegisterLOMSHandlerServer(ctx context.Context, mux *runtime.ServeMux, server LOMSServer) error { + + mux.Handle("POST", pattern_LOMS_OrderCreate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.LOMS/OrderCreate", runtime.WithHTTPPathPattern("/order/create")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LOMS_OrderCreate_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderCreate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_LOMS_OrderInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.LOMS/OrderInfo", runtime.WithHTTPPathPattern("/order/info")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LOMS_OrderInfo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_LOMS_OrderPay_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.LOMS/OrderPay", runtime.WithHTTPPathPattern("/order/pay")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LOMS_OrderPay_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderPay_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_LOMS_OrderCancel_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.LOMS/OrderCancel", runtime.WithHTTPPathPattern("/order/cancel")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LOMS_OrderCancel_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderCancel_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_LOMS_StocksInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.LOMS/StocksInfo", runtime.WithHTTPPathPattern("/stock/info")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LOMS_StocksInfo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_StocksInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterLOMSHandlerFromEndpoint is same as RegisterLOMSHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterLOMSHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterLOMSHandler(ctx, mux, conn) +} + +// RegisterLOMSHandler registers the http handlers for service LOMS to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterLOMSHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterLOMSHandlerClient(ctx, mux, NewLOMSClient(conn)) +} + +// RegisterLOMSHandlerClient registers the http handlers for service LOMS +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "LOMSClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LOMSClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "LOMSClient" to call the correct interceptors. +func RegisterLOMSHandlerClient(ctx context.Context, mux *runtime.ServeMux, client LOMSClient) error { + + mux.Handle("POST", pattern_LOMS_OrderCreate_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.LOMS/OrderCreate", runtime.WithHTTPPathPattern("/order/create")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LOMS_OrderCreate_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderCreate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_LOMS_OrderInfo_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.LOMS/OrderInfo", runtime.WithHTTPPathPattern("/order/info")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LOMS_OrderInfo_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_LOMS_OrderPay_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.LOMS/OrderPay", runtime.WithHTTPPathPattern("/order/pay")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LOMS_OrderPay_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderPay_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_LOMS_OrderCancel_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.LOMS/OrderCancel", runtime.WithHTTPPathPattern("/order/cancel")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LOMS_OrderCancel_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_OrderCancel_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_LOMS_StocksInfo_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) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.LOMS/StocksInfo", runtime.WithHTTPPathPattern("/stock/info")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LOMS_StocksInfo_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LOMS_StocksInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_LOMS_OrderCreate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"order", "create"}, "")) + + pattern_LOMS_OrderInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"order", "info"}, "")) + + pattern_LOMS_OrderPay_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"order", "pay"}, "")) + + pattern_LOMS_OrderCancel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"order", "cancel"}, "")) + + pattern_LOMS_StocksInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"stock", "info"}, "")) +) + +var ( + forward_LOMS_OrderCreate_0 = runtime.ForwardResponseMessage + + forward_LOMS_OrderInfo_0 = runtime.ForwardResponseMessage + + forward_LOMS_OrderPay_0 = runtime.ForwardResponseMessage + + forward_LOMS_OrderCancel_0 = runtime.ForwardResponseMessage + + forward_LOMS_StocksInfo_0 = runtime.ForwardResponseMessage +) diff --git a/pkg/api/loms/v1/loms.pb.validate.go b/pkg/api/loms/v1/loms.pb.validate.go new file mode 100644 index 0000000..3dbf72e --- /dev/null +++ b/pkg/api/loms/v1/loms.pb.validate.go @@ -0,0 +1,1111 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: loms/v1/loms.proto + +package loms + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on OrderItem with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *OrderItem) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderItem with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in OrderItemMultiError, or nil +// if none found. +func (m *OrderItem) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderItem) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetSku() <= 0 { + err := OrderItemValidationError{ + field: "Sku", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if m.GetCount() <= 0 { + err := OrderItemValidationError{ + field: "Count", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return OrderItemMultiError(errors) + } + + return nil +} + +// OrderItemMultiError is an error wrapping multiple validation errors returned +// by OrderItem.ValidateAll() if the designated constraints aren't met. +type OrderItemMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderItemMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderItemMultiError) AllErrors() []error { return m } + +// OrderItemValidationError is the validation error returned by +// OrderItem.Validate if the designated constraints aren't met. +type OrderItemValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderItemValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderItemValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderItemValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderItemValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderItemValidationError) ErrorName() string { return "OrderItemValidationError" } + +// Error satisfies the builtin error interface +func (e OrderItemValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderItem.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderItemValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderItemValidationError{} + +// Validate checks the field values on OrderCreateRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *OrderCreateRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderCreateRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OrderCreateRequestMultiError, or nil if none found. +func (m *OrderCreateRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderCreateRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetUserId() <= 0 { + err := OrderCreateRequestValidationError{ + field: "UserId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(m.GetItems()) < 1 { + err := OrderCreateRequestValidationError{ + field: "Items", + reason: "value must contain at least 1 item(s)", + } + if !all { + return err + } + errors = append(errors, err) + } + + for idx, item := range m.GetItems() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OrderCreateRequestValidationError{ + field: fmt.Sprintf("Items[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OrderCreateRequestValidationError{ + field: fmt.Sprintf("Items[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OrderCreateRequestValidationError{ + field: fmt.Sprintf("Items[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return OrderCreateRequestMultiError(errors) + } + + return nil +} + +// OrderCreateRequestMultiError is an error wrapping multiple validation errors +// returned by OrderCreateRequest.ValidateAll() if the designated constraints +// aren't met. +type OrderCreateRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderCreateRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderCreateRequestMultiError) AllErrors() []error { return m } + +// OrderCreateRequestValidationError is the validation error returned by +// OrderCreateRequest.Validate if the designated constraints aren't met. +type OrderCreateRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderCreateRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderCreateRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderCreateRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderCreateRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderCreateRequestValidationError) ErrorName() string { + return "OrderCreateRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e OrderCreateRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderCreateRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderCreateRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderCreateRequestValidationError{} + +// Validate checks the field values on OrderCreateResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *OrderCreateResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderCreateResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OrderCreateResponseMultiError, or nil if none found. +func (m *OrderCreateResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderCreateResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for OrderId + + if len(errors) > 0 { + return OrderCreateResponseMultiError(errors) + } + + return nil +} + +// OrderCreateResponseMultiError is an error wrapping multiple validation +// errors returned by OrderCreateResponse.ValidateAll() if the designated +// constraints aren't met. +type OrderCreateResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderCreateResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderCreateResponseMultiError) AllErrors() []error { return m } + +// OrderCreateResponseValidationError is the validation error returned by +// OrderCreateResponse.Validate if the designated constraints aren't met. +type OrderCreateResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderCreateResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderCreateResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderCreateResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderCreateResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderCreateResponseValidationError) ErrorName() string { + return "OrderCreateResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e OrderCreateResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderCreateResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderCreateResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderCreateResponseValidationError{} + +// Validate checks the field values on OrderInfoRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *OrderInfoRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderInfoRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OrderInfoRequestMultiError, or nil if none found. +func (m *OrderInfoRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderInfoRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetOrderId() <= 0 { + err := OrderInfoRequestValidationError{ + field: "OrderId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return OrderInfoRequestMultiError(errors) + } + + return nil +} + +// OrderInfoRequestMultiError is an error wrapping multiple validation errors +// returned by OrderInfoRequest.ValidateAll() if the designated constraints +// aren't met. +type OrderInfoRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderInfoRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderInfoRequestMultiError) AllErrors() []error { return m } + +// OrderInfoRequestValidationError is the validation error returned by +// OrderInfoRequest.Validate if the designated constraints aren't met. +type OrderInfoRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderInfoRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderInfoRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderInfoRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderInfoRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderInfoRequestValidationError) ErrorName() string { return "OrderInfoRequestValidationError" } + +// Error satisfies the builtin error interface +func (e OrderInfoRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderInfoRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderInfoRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderInfoRequestValidationError{} + +// Validate checks the field values on OrderInfoResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *OrderInfoResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderInfoResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OrderInfoResponseMultiError, or nil if none found. +func (m *OrderInfoResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderInfoResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Status + + // no validation rules for UserId + + for idx, item := range m.GetItems() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, OrderInfoResponseValidationError{ + field: fmt.Sprintf("Items[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, OrderInfoResponseValidationError{ + field: fmt.Sprintf("Items[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return OrderInfoResponseValidationError{ + field: fmt.Sprintf("Items[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return OrderInfoResponseMultiError(errors) + } + + return nil +} + +// OrderInfoResponseMultiError is an error wrapping multiple validation errors +// returned by OrderInfoResponse.ValidateAll() if the designated constraints +// aren't met. +type OrderInfoResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderInfoResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderInfoResponseMultiError) AllErrors() []error { return m } + +// OrderInfoResponseValidationError is the validation error returned by +// OrderInfoResponse.Validate if the designated constraints aren't met. +type OrderInfoResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderInfoResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderInfoResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderInfoResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderInfoResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderInfoResponseValidationError) ErrorName() string { + return "OrderInfoResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e OrderInfoResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderInfoResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderInfoResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderInfoResponseValidationError{} + +// Validate checks the field values on OrderPayRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *OrderPayRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderPayRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OrderPayRequestMultiError, or nil if none found. +func (m *OrderPayRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderPayRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetOrderId() <= 0 { + err := OrderPayRequestValidationError{ + field: "OrderId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return OrderPayRequestMultiError(errors) + } + + return nil +} + +// OrderPayRequestMultiError is an error wrapping multiple validation errors +// returned by OrderPayRequest.ValidateAll() if the designated constraints +// aren't met. +type OrderPayRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderPayRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderPayRequestMultiError) AllErrors() []error { return m } + +// OrderPayRequestValidationError is the validation error returned by +// OrderPayRequest.Validate if the designated constraints aren't met. +type OrderPayRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderPayRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderPayRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderPayRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderPayRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderPayRequestValidationError) ErrorName() string { return "OrderPayRequestValidationError" } + +// Error satisfies the builtin error interface +func (e OrderPayRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderPayRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderPayRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderPayRequestValidationError{} + +// Validate checks the field values on OrderCancelRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *OrderCancelRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on OrderCancelRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// OrderCancelRequestMultiError, or nil if none found. +func (m *OrderCancelRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *OrderCancelRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetOrderId() <= 0 { + err := OrderCancelRequestValidationError{ + field: "OrderId", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return OrderCancelRequestMultiError(errors) + } + + return nil +} + +// OrderCancelRequestMultiError is an error wrapping multiple validation errors +// returned by OrderCancelRequest.ValidateAll() if the designated constraints +// aren't met. +type OrderCancelRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m OrderCancelRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m OrderCancelRequestMultiError) AllErrors() []error { return m } + +// OrderCancelRequestValidationError is the validation error returned by +// OrderCancelRequest.Validate if the designated constraints aren't met. +type OrderCancelRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e OrderCancelRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e OrderCancelRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e OrderCancelRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e OrderCancelRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e OrderCancelRequestValidationError) ErrorName() string { + return "OrderCancelRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e OrderCancelRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sOrderCancelRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = OrderCancelRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = OrderCancelRequestValidationError{} + +// Validate checks the field values on StocksInfoRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *StocksInfoRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on StocksInfoRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// StocksInfoRequestMultiError, or nil if none found. +func (m *StocksInfoRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *StocksInfoRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if m.GetSku() <= 0 { + err := StocksInfoRequestValidationError{ + field: "Sku", + reason: "value must be greater than 0", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return StocksInfoRequestMultiError(errors) + } + + return nil +} + +// StocksInfoRequestMultiError is an error wrapping multiple validation errors +// returned by StocksInfoRequest.ValidateAll() if the designated constraints +// aren't met. +type StocksInfoRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m StocksInfoRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m StocksInfoRequestMultiError) AllErrors() []error { return m } + +// StocksInfoRequestValidationError is the validation error returned by +// StocksInfoRequest.Validate if the designated constraints aren't met. +type StocksInfoRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StocksInfoRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StocksInfoRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StocksInfoRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StocksInfoRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StocksInfoRequestValidationError) ErrorName() string { + return "StocksInfoRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e StocksInfoRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStocksInfoRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StocksInfoRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StocksInfoRequestValidationError{} + +// Validate checks the field values on StocksInfoResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *StocksInfoResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on StocksInfoResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// StocksInfoResponseMultiError, or nil if none found. +func (m *StocksInfoResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *StocksInfoResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Count + + if len(errors) > 0 { + return StocksInfoResponseMultiError(errors) + } + + return nil +} + +// StocksInfoResponseMultiError is an error wrapping multiple validation errors +// returned by StocksInfoResponse.ValidateAll() if the designated constraints +// aren't met. +type StocksInfoResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m StocksInfoResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m StocksInfoResponseMultiError) AllErrors() []error { return m } + +// StocksInfoResponseValidationError is the validation error returned by +// StocksInfoResponse.Validate if the designated constraints aren't met. +type StocksInfoResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StocksInfoResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StocksInfoResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StocksInfoResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StocksInfoResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StocksInfoResponseValidationError) ErrorName() string { + return "StocksInfoResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e StocksInfoResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStocksInfoResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StocksInfoResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StocksInfoResponseValidationError{} diff --git a/pkg/api/loms/v1/loms_grpc.pb.go b/pkg/api/loms/v1/loms_grpc.pb.go new file mode 100644 index 0000000..5ca67d3 --- /dev/null +++ b/pkg/api/loms/v1/loms_grpc.pb.go @@ -0,0 +1,250 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v6.30.0 +// source: loms/v1/loms.proto + +package loms + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// LOMSClient is the client API for LOMS service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type LOMSClient interface { + OrderCreate(ctx context.Context, in *OrderCreateRequest, opts ...grpc.CallOption) (*OrderCreateResponse, error) + OrderInfo(ctx context.Context, in *OrderInfoRequest, opts ...grpc.CallOption) (*OrderInfoResponse, error) + OrderPay(ctx context.Context, in *OrderPayRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + OrderCancel(ctx context.Context, in *OrderCancelRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + StocksInfo(ctx context.Context, in *StocksInfoRequest, opts ...grpc.CallOption) (*StocksInfoResponse, error) +} + +type lOMSClient struct { + cc grpc.ClientConnInterface +} + +func NewLOMSClient(cc grpc.ClientConnInterface) LOMSClient { + return &lOMSClient{cc} +} + +func (c *lOMSClient) OrderCreate(ctx context.Context, in *OrderCreateRequest, opts ...grpc.CallOption) (*OrderCreateResponse, error) { + out := new(OrderCreateResponse) + err := c.cc.Invoke(ctx, "/LOMS/OrderCreate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *lOMSClient) OrderInfo(ctx context.Context, in *OrderInfoRequest, opts ...grpc.CallOption) (*OrderInfoResponse, error) { + out := new(OrderInfoResponse) + err := c.cc.Invoke(ctx, "/LOMS/OrderInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *lOMSClient) OrderPay(ctx context.Context, in *OrderPayRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/LOMS/OrderPay", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *lOMSClient) OrderCancel(ctx context.Context, in *OrderCancelRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/LOMS/OrderCancel", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *lOMSClient) StocksInfo(ctx context.Context, in *StocksInfoRequest, opts ...grpc.CallOption) (*StocksInfoResponse, error) { + out := new(StocksInfoResponse) + err := c.cc.Invoke(ctx, "/LOMS/StocksInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// LOMSServer is the server API for LOMS service. +// All implementations must embed UnimplementedLOMSServer +// for forward compatibility +type LOMSServer interface { + OrderCreate(context.Context, *OrderCreateRequest) (*OrderCreateResponse, error) + OrderInfo(context.Context, *OrderInfoRequest) (*OrderInfoResponse, error) + OrderPay(context.Context, *OrderPayRequest) (*emptypb.Empty, error) + OrderCancel(context.Context, *OrderCancelRequest) (*emptypb.Empty, error) + StocksInfo(context.Context, *StocksInfoRequest) (*StocksInfoResponse, error) + mustEmbedUnimplementedLOMSServer() +} + +// UnimplementedLOMSServer must be embedded to have forward compatible implementations. +type UnimplementedLOMSServer struct { +} + +func (UnimplementedLOMSServer) OrderCreate(context.Context, *OrderCreateRequest) (*OrderCreateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OrderCreate not implemented") +} +func (UnimplementedLOMSServer) OrderInfo(context.Context, *OrderInfoRequest) (*OrderInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OrderInfo not implemented") +} +func (UnimplementedLOMSServer) OrderPay(context.Context, *OrderPayRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method OrderPay not implemented") +} +func (UnimplementedLOMSServer) OrderCancel(context.Context, *OrderCancelRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method OrderCancel not implemented") +} +func (UnimplementedLOMSServer) StocksInfo(context.Context, *StocksInfoRequest) (*StocksInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StocksInfo not implemented") +} +func (UnimplementedLOMSServer) mustEmbedUnimplementedLOMSServer() {} + +// UnsafeLOMSServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to LOMSServer will +// result in compilation errors. +type UnsafeLOMSServer interface { + mustEmbedUnimplementedLOMSServer() +} + +func RegisterLOMSServer(s grpc.ServiceRegistrar, srv LOMSServer) { + s.RegisterService(&LOMS_ServiceDesc, srv) +} + +func _LOMS_OrderCreate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OrderCreateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LOMSServer).OrderCreate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/LOMS/OrderCreate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LOMSServer).OrderCreate(ctx, req.(*OrderCreateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _LOMS_OrderInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OrderInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LOMSServer).OrderInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/LOMS/OrderInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LOMSServer).OrderInfo(ctx, req.(*OrderInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _LOMS_OrderPay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OrderPayRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LOMSServer).OrderPay(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/LOMS/OrderPay", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LOMSServer).OrderPay(ctx, req.(*OrderPayRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _LOMS_OrderCancel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OrderCancelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LOMSServer).OrderCancel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/LOMS/OrderCancel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LOMSServer).OrderCancel(ctx, req.(*OrderCancelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _LOMS_StocksInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StocksInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LOMSServer).StocksInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/LOMS/StocksInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LOMSServer).StocksInfo(ctx, req.(*StocksInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// LOMS_ServiceDesc is the grpc.ServiceDesc for LOMS service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var LOMS_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "LOMS", + HandlerType: (*LOMSServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "OrderCreate", + Handler: _LOMS_OrderCreate_Handler, + }, + { + MethodName: "OrderInfo", + Handler: _LOMS_OrderInfo_Handler, + }, + { + MethodName: "OrderPay", + Handler: _LOMS_OrderPay_Handler, + }, + { + MethodName: "OrderCancel", + Handler: _LOMS_OrderCancel_Handler, + }, + { + MethodName: "StocksInfo", + Handler: _LOMS_StocksInfo_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "loms/v1/loms.proto", +} diff --git a/pkg/go.mod b/pkg/go.mod new file mode 100644 index 0000000..822152c --- /dev/null +++ b/pkg/go.mod @@ -0,0 +1,18 @@ +module route256/pkg + +go 1.23.9 + +require ( + github.com/envoyproxy/protoc-gen-validate v1.2.1 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 + google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 + google.golang.org/grpc v1.73.0 + google.golang.org/protobuf v1.36.6 +) + +require ( + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect +) diff --git a/pkg/go.sum b/pkg/go.sum new file mode 100644 index 0000000..7a5667e --- /dev/null +++ b/pkg/go.sum @@ -0,0 +1,40 @@ +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= +google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=