From b083cccc09cceb78bf5238a8968ee6a48b2863ee Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 27 May 2025 03:41:52 +0300 Subject: [PATCH] Add gRPC server implementation and database integration for marketplace and products --- .env | 12 + .../v1/marketplace/marketplace.pb.go | 200 +++++++ .../v1/marketplace/marketplace_grpc.pb.go | 121 +++++ api/generated/v1/ozon/products/products.pb.go | 430 ++++++++++++++++ .../v1/ozon/products/products_grpc.pb.go | 126 +++++ api/generated/v1/test.pb.go | 486 ------------------ api/generated/v1/test_grpc.pb.go | 235 --------- api/generated/v1/wb/products/products.pb.go | 60 +++ .../v1/wb/products/products_grpc.pb.go | 76 +++ .../v1/yandexmarket/products/products.pb.go | 60 +++ .../yandexmarket/products/products_grpc.pb.go | 76 +++ api/proto/v1 | 2 +- cmd/server/main.go | 173 +++---- generate_grpc.sh | 32 +- go.mod | 68 +-- go.sum | 197 +++---- internal/db/sqlc.yaml | 2 +- internal/marketplace/adapter_grpc.go | 46 ++ internal/marketplace/db/db.go | 32 ++ internal/marketplace/db/models.go | 17 + internal/marketplace/db/query.sql | 3 + internal/marketplace/db/query.sql.go | 28 + internal/marketplace/db/schema.sql | 9 + internal/marketplace/db/sqlc.yaml | 10 + internal/marketplace/entities.go | 8 + internal/marketplace/repository.go | 8 + internal/marketplace/repository_db.go | 29 ++ internal/ozon/common.go | 35 ++ internal/ozon/products/adapter_grpc.go | 62 +++ internal/ozon/products/entities.go | 5 + internal/ozon/products/mapping/converter.go | 20 + .../products/mapping/generated/generated.go | 56 ++ internal/ozon/products/repository.go | 8 + internal/ozon/products/repository_api.go | 118 +++++ internal/ozon/rate_limiter.go | 67 +++ internal/redis/client.go | 36 ++ internal/test/adapters/http.go | 19 - internal/test/db/generated/db.go | 31 -- internal/test/db/generated/models.go | 10 - internal/test/db/generated/queries.sql.go | 55 -- internal/test/db/queries.sql | 11 - internal/test/repository.go | 42 -- internal/test/service.go | 37 -- щдв | 225 ++++++++ 44 files changed, 2182 insertions(+), 1201 deletions(-) create mode 100644 .env create mode 100644 api/generated/v1/marketplace/marketplace.pb.go create mode 100644 api/generated/v1/marketplace/marketplace_grpc.pb.go create mode 100644 api/generated/v1/ozon/products/products.pb.go create mode 100644 api/generated/v1/ozon/products/products_grpc.pb.go delete mode 100755 api/generated/v1/test.pb.go delete mode 100755 api/generated/v1/test_grpc.pb.go create mode 100644 api/generated/v1/wb/products/products.pb.go create mode 100644 api/generated/v1/wb/products/products_grpc.pb.go create mode 100644 api/generated/v1/yandexmarket/products/products.pb.go create mode 100644 api/generated/v1/yandexmarket/products/products_grpc.pb.go create mode 100644 internal/marketplace/adapter_grpc.go create mode 100644 internal/marketplace/db/db.go create mode 100644 internal/marketplace/db/models.go create mode 100644 internal/marketplace/db/query.sql create mode 100644 internal/marketplace/db/query.sql.go create mode 100644 internal/marketplace/db/schema.sql create mode 100644 internal/marketplace/db/sqlc.yaml create mode 100644 internal/marketplace/entities.go create mode 100644 internal/marketplace/repository.go create mode 100644 internal/marketplace/repository_db.go create mode 100644 internal/ozon/common.go create mode 100644 internal/ozon/products/adapter_grpc.go create mode 100644 internal/ozon/products/entities.go create mode 100644 internal/ozon/products/mapping/converter.go create mode 100644 internal/ozon/products/mapping/generated/generated.go create mode 100644 internal/ozon/products/repository.go create mode 100644 internal/ozon/products/repository_api.go create mode 100644 internal/ozon/rate_limiter.go create mode 100644 internal/redis/client.go delete mode 100755 internal/test/adapters/http.go delete mode 100755 internal/test/db/generated/db.go delete mode 100755 internal/test/db/generated/models.go delete mode 100755 internal/test/db/generated/queries.sql.go delete mode 100755 internal/test/db/queries.sql delete mode 100755 internal/test/repository.go delete mode 100755 internal/test/service.go create mode 100644 щдв diff --git a/.env b/.env new file mode 100644 index 0000000..727105b --- /dev/null +++ b/.env @@ -0,0 +1,12 @@ +# Redis +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD=ELdhsgqJt5QZUSWKU5vY3D9CXa1a0teIceeHqvCtoPkrDJ0Lge7XIe8187gFjd0qZLv9zwhGr62MqY + +# PostgreSQL +POSTGRES_LOGIN=postgres +POSTGRES_PASSWORD=GjitkeYf%5Beq +POSTGRES_PORT=5432 +POSTGRES_DATABASE=sipro +POSTGRES_HOST=localhost +POSTGRES_URL="postgresql://${POSTGRES_LOGIN}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DATABASE}" diff --git a/api/generated/v1/marketplace/marketplace.pb.go b/api/generated/v1/marketplace/marketplace.pb.go new file mode 100644 index 0000000..8e19089 --- /dev/null +++ b/api/generated/v1/marketplace/marketplace.pb.go @@ -0,0 +1,200 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.31.0 +// source: marketplace/marketplace.proto + +package marketplace + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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 GetMarketplaceByIdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + MarketplaceId uint64 `protobuf:"varint,1,opt,name=marketplace_id,json=marketplaceId,proto3" json:"marketplace_id,omitempty"` // ID of the marketplace to retrieve + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetMarketplaceByIdRequest) Reset() { + *x = GetMarketplaceByIdRequest{} + mi := &file_marketplace_marketplace_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetMarketplaceByIdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMarketplaceByIdRequest) ProtoMessage() {} + +func (x *GetMarketplaceByIdRequest) ProtoReflect() protoreflect.Message { + mi := &file_marketplace_marketplace_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMarketplaceByIdRequest.ProtoReflect.Descriptor instead. +func (*GetMarketplaceByIdRequest) Descriptor() ([]byte, []int) { + return file_marketplace_marketplace_proto_rawDescGZIP(), []int{0} +} + +func (x *GetMarketplaceByIdRequest) GetMarketplaceId() uint64 { + if x != nil { + return x.MarketplaceId + } + return 0 +} + +type Marketplace struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + BaseMarketplace uint32 `protobuf:"varint,2,opt,name=base_marketplace,json=baseMarketplace,proto3" json:"base_marketplace,omitempty"` // ID of the base marketplace + AuthData string `protobuf:"bytes,3,opt,name=auth_data,json=authData,proto3" json:"auth_data,omitempty"` // Authentication data for the marketplace + WarehouseId string `protobuf:"bytes,4,opt,name=warehouse_id,json=warehouseId,proto3" json:"warehouse_id,omitempty"` // ID of the warehouse associated with the marketplace + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Marketplace) Reset() { + *x = Marketplace{} + mi := &file_marketplace_marketplace_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Marketplace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Marketplace) ProtoMessage() {} + +func (x *Marketplace) ProtoReflect() protoreflect.Message { + mi := &file_marketplace_marketplace_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Marketplace.ProtoReflect.Descriptor instead. +func (*Marketplace) Descriptor() ([]byte, []int) { + return file_marketplace_marketplace_proto_rawDescGZIP(), []int{1} +} + +func (x *Marketplace) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Marketplace) GetBaseMarketplace() uint32 { + if x != nil { + return x.BaseMarketplace + } + return 0 +} + +func (x *Marketplace) GetAuthData() string { + if x != nil { + return x.AuthData + } + return "" +} + +func (x *Marketplace) GetWarehouseId() string { + if x != nil { + return x.WarehouseId + } + return "" +} + +var File_marketplace_marketplace_proto protoreflect.FileDescriptor + +const file_marketplace_marketplace_proto_rawDesc = "" + + "\n" + + "\x1dmarketplace/marketplace.proto\x12\vmarketplace\"B\n" + + "\x19GetMarketplaceByIdRequest\x12%\n" + + "\x0emarketplace_id\x18\x01 \x01(\x04R\rmarketplaceId\"\x88\x01\n" + + "\vMarketplace\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x04R\x02id\x12)\n" + + "\x10base_marketplace\x18\x02 \x01(\rR\x0fbaseMarketplace\x12\x1b\n" + + "\tauth_data\x18\x03 \x01(\tR\bauthData\x12!\n" + + "\fwarehouse_id\x18\x04 \x01(\tR\vwarehouseId2l\n" + + "\x12MarketplaceService\x12V\n" + + "\x12GetMarketplaceById\x12&.marketplace.GetMarketplaceByIdRequest\x1a\x18.marketplace.MarketplaceB\x0fZ\r./marketplaceb\x06proto3" + +var ( + file_marketplace_marketplace_proto_rawDescOnce sync.Once + file_marketplace_marketplace_proto_rawDescData []byte +) + +func file_marketplace_marketplace_proto_rawDescGZIP() []byte { + file_marketplace_marketplace_proto_rawDescOnce.Do(func() { + file_marketplace_marketplace_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_marketplace_marketplace_proto_rawDesc), len(file_marketplace_marketplace_proto_rawDesc))) + }) + return file_marketplace_marketplace_proto_rawDescData +} + +var file_marketplace_marketplace_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_marketplace_marketplace_proto_goTypes = []any{ + (*GetMarketplaceByIdRequest)(nil), // 0: marketplace.GetMarketplaceByIdRequest + (*Marketplace)(nil), // 1: marketplace.Marketplace +} +var file_marketplace_marketplace_proto_depIdxs = []int32{ + 0, // 0: marketplace.MarketplaceService.GetMarketplaceById:input_type -> marketplace.GetMarketplaceByIdRequest + 1, // 1: marketplace.MarketplaceService.GetMarketplaceById:output_type -> marketplace.Marketplace + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_marketplace_marketplace_proto_init() } +func file_marketplace_marketplace_proto_init() { + if File_marketplace_marketplace_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_marketplace_marketplace_proto_rawDesc), len(file_marketplace_marketplace_proto_rawDesc)), + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_marketplace_marketplace_proto_goTypes, + DependencyIndexes: file_marketplace_marketplace_proto_depIdxs, + MessageInfos: file_marketplace_marketplace_proto_msgTypes, + }.Build() + File_marketplace_marketplace_proto = out.File + file_marketplace_marketplace_proto_goTypes = nil + file_marketplace_marketplace_proto_depIdxs = nil +} diff --git a/api/generated/v1/marketplace/marketplace_grpc.pb.go b/api/generated/v1/marketplace/marketplace_grpc.pb.go new file mode 100644 index 0000000..1c6161d --- /dev/null +++ b/api/generated/v1/marketplace/marketplace_grpc.pb.go @@ -0,0 +1,121 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.0 +// source: marketplace/marketplace.proto + +package marketplace + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// 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.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + MarketplaceService_GetMarketplaceById_FullMethodName = "/marketplace.MarketplaceService/GetMarketplaceById" +) + +// MarketplaceServiceClient is the client API for MarketplaceService 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 MarketplaceServiceClient interface { + GetMarketplaceById(ctx context.Context, in *GetMarketplaceByIdRequest, opts ...grpc.CallOption) (*Marketplace, error) +} + +type marketplaceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMarketplaceServiceClient(cc grpc.ClientConnInterface) MarketplaceServiceClient { + return &marketplaceServiceClient{cc} +} + +func (c *marketplaceServiceClient) GetMarketplaceById(ctx context.Context, in *GetMarketplaceByIdRequest, opts ...grpc.CallOption) (*Marketplace, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Marketplace) + err := c.cc.Invoke(ctx, MarketplaceService_GetMarketplaceById_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MarketplaceServiceServer is the server API for MarketplaceService service. +// All implementations must embed UnimplementedMarketplaceServiceServer +// for forward compatibility. +type MarketplaceServiceServer interface { + GetMarketplaceById(context.Context, *GetMarketplaceByIdRequest) (*Marketplace, error) + mustEmbedUnimplementedMarketplaceServiceServer() +} + +// UnimplementedMarketplaceServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedMarketplaceServiceServer struct{} + +func (UnimplementedMarketplaceServiceServer) GetMarketplaceById(context.Context, *GetMarketplaceByIdRequest) (*Marketplace, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMarketplaceById not implemented") +} +func (UnimplementedMarketplaceServiceServer) mustEmbedUnimplementedMarketplaceServiceServer() {} +func (UnimplementedMarketplaceServiceServer) testEmbeddedByValue() {} + +// UnsafeMarketplaceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MarketplaceServiceServer will +// result in compilation errors. +type UnsafeMarketplaceServiceServer interface { + mustEmbedUnimplementedMarketplaceServiceServer() +} + +func RegisterMarketplaceServiceServer(s grpc.ServiceRegistrar, srv MarketplaceServiceServer) { + // If the following call pancis, it indicates UnimplementedMarketplaceServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&MarketplaceService_ServiceDesc, srv) +} + +func _MarketplaceService_GetMarketplaceById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMarketplaceByIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MarketplaceServiceServer).GetMarketplaceById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MarketplaceService_GetMarketplaceById_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MarketplaceServiceServer).GetMarketplaceById(ctx, req.(*GetMarketplaceByIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// MarketplaceService_ServiceDesc is the grpc.ServiceDesc for MarketplaceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var MarketplaceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "marketplace.MarketplaceService", + HandlerType: (*MarketplaceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetMarketplaceById", + Handler: _MarketplaceService_GetMarketplaceById_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "marketplace/marketplace.proto", +} diff --git a/api/generated/v1/ozon/products/products.pb.go b/api/generated/v1/ozon/products/products.pb.go new file mode 100644 index 0000000..73397c6 --- /dev/null +++ b/api/generated/v1/ozon/products/products.pb.go @@ -0,0 +1,430 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.31.0 +// source: ozon/products.proto + +package products + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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 GetListOfProductsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetListOfProductsRequest) Reset() { + *x = GetListOfProductsRequest{} + mi := &file_ozon_products_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetListOfProductsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetListOfProductsRequest) ProtoMessage() {} + +func (x *GetListOfProductsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ozon_products_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetListOfProductsRequest.ProtoReflect.Descriptor instead. +func (*GetListOfProductsRequest) Descriptor() ([]byte, []int) { + return file_ozon_products_proto_rawDescGZIP(), []int{0} +} + +type GetListOfProductsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetListOfProductsResponse) Reset() { + *x = GetListOfProductsResponse{} + mi := &file_ozon_products_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetListOfProductsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetListOfProductsResponse) ProtoMessage() {} + +func (x *GetListOfProductsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ozon_products_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetListOfProductsResponse.ProtoReflect.Descriptor instead. +func (*GetListOfProductsResponse) Descriptor() ([]byte, []int) { + return file_ozon_products_proto_rawDescGZIP(), []int{1} +} + +func (x *GetListOfProductsResponse) GetProducts() []*Product { + if x != nil { + return x.Products + } + return nil +} + +type Product struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + OfferId string `protobuf:"bytes,2,opt,name=offer_id,json=offerId,proto3" json:"offer_id,omitempty"` + Stocks *Product_Stocks `protobuf:"bytes,3,opt,name=stocks,proto3" json:"stocks,omitempty"` + Barcodes []string `protobuf:"bytes,4,rep,name=barcodes,proto3" json:"barcodes,omitempty"` + Statuses *Product_Status `protobuf:"bytes,5,opt,name=statuses,proto3" json:"statuses,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Product) Reset() { + *x = Product{} + mi := &file_ozon_products_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Product) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product) ProtoMessage() {} + +func (x *Product) ProtoReflect() protoreflect.Message { + mi := &file_ozon_products_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product.ProtoReflect.Descriptor instead. +func (*Product) Descriptor() ([]byte, []int) { + return file_ozon_products_proto_rawDescGZIP(), []int{2} +} + +func (x *Product) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Product) GetOfferId() string { + if x != nil { + return x.OfferId + } + return "" +} + +func (x *Product) GetStocks() *Product_Stocks { + if x != nil { + return x.Stocks + } + return nil +} + +func (x *Product) GetBarcodes() []string { + if x != nil { + return x.Barcodes + } + return nil +} + +func (x *Product) GetStatuses() *Product_Status { + if x != nil { + return x.Statuses + } + return nil +} + +type Product_Status struct { + state protoimpl.MessageState `protogen:"open.v1"` + StatusName string `protobuf:"bytes,1,opt,name=status_name,json=statusName,proto3" json:"status_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Product_Status) Reset() { + *x = Product_Status{} + mi := &file_ozon_products_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Product_Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product_Status) ProtoMessage() {} + +func (x *Product_Status) ProtoReflect() protoreflect.Message { + mi := &file_ozon_products_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product_Status.ProtoReflect.Descriptor instead. +func (*Product_Status) Descriptor() ([]byte, []int) { + return file_ozon_products_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *Product_Status) GetStatusName() string { + if x != nil { + return x.StatusName + } + return "" +} + +type Product_Stocks struct { + state protoimpl.MessageState `protogen:"open.v1"` + Stocks []*Product_Stock `protobuf:"bytes,1,rep,name=stocks,proto3" json:"stocks,omitempty"` + HasStock bool `protobuf:"varint,2,opt,name=has_stock,json=hasStock,proto3" json:"has_stock,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Product_Stocks) Reset() { + *x = Product_Stocks{} + mi := &file_ozon_products_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Product_Stocks) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product_Stocks) ProtoMessage() {} + +func (x *Product_Stocks) ProtoReflect() protoreflect.Message { + mi := &file_ozon_products_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product_Stocks.ProtoReflect.Descriptor instead. +func (*Product_Stocks) Descriptor() ([]byte, []int) { + return file_ozon_products_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *Product_Stocks) GetStocks() []*Product_Stock { + if x != nil { + return x.Stocks + } + return nil +} + +func (x *Product_Stocks) GetHasStock() bool { + if x != nil { + return x.HasStock + } + return false +} + +type Product_Stock struct { + state protoimpl.MessageState `protogen:"open.v1"` + Present int64 `protobuf:"varint,1,opt,name=present,proto3" json:"present,omitempty"` + Reserved int64 `protobuf:"varint,2,opt,name=reserved,proto3" json:"reserved,omitempty"` + SKU int64 `protobuf:"varint,3,opt,name=SKU,proto3" json:"SKU,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Product_Stock) Reset() { + *x = Product_Stock{} + mi := &file_ozon_products_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Product_Stock) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product_Stock) ProtoMessage() {} + +func (x *Product_Stock) ProtoReflect() protoreflect.Message { + mi := &file_ozon_products_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product_Stock.ProtoReflect.Descriptor instead. +func (*Product_Stock) Descriptor() ([]byte, []int) { + return file_ozon_products_proto_rawDescGZIP(), []int{2, 2} +} + +func (x *Product_Stock) GetPresent() int64 { + if x != nil { + return x.Present + } + return 0 +} + +func (x *Product_Stock) GetReserved() int64 { + if x != nil { + return x.Reserved + } + return 0 +} + +func (x *Product_Stock) GetSKU() int64 { + if x != nil { + return x.SKU + } + return 0 +} + +func (x *Product_Stock) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +var File_ozon_products_proto protoreflect.FileDescriptor + +const file_ozon_products_proto_rawDesc = "" + + "\n" + + "\x13ozon/products.proto\x12\rozon.products\x1a\x1fgoogle/protobuf/timestamp.proto\"\x1a\n" + + "\x18GetListOfProductsRequest\"O\n" + + "\x19GetListOfProductsResponse\x122\n" + + "\bproducts\x18\x01 \x03(\v2\x16.ozon.products.ProductR\bproducts\"\xb3\x03\n" + + "\aProduct\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x19\n" + + "\boffer_id\x18\x02 \x01(\tR\aofferId\x125\n" + + "\x06stocks\x18\x03 \x01(\v2\x1d.ozon.products.Product.StocksR\x06stocks\x12\x1a\n" + + "\bbarcodes\x18\x04 \x03(\tR\bbarcodes\x129\n" + + "\bstatuses\x18\x05 \x01(\v2\x1d.ozon.products.Product.StatusR\bstatuses\x1a)\n" + + "\x06Status\x12\x1f\n" + + "\vstatus_name\x18\x01 \x01(\tR\n" + + "statusName\x1a[\n" + + "\x06Stocks\x124\n" + + "\x06stocks\x18\x01 \x03(\v2\x1c.ozon.products.Product.StockR\x06stocks\x12\x1b\n" + + "\thas_stock\x18\x02 \x01(\bR\bhasStock\x1ag\n" + + "\x05Stock\x12\x18\n" + + "\apresent\x18\x01 \x01(\x03R\apresent\x12\x1a\n" + + "\breserved\x18\x02 \x01(\x03R\breserved\x12\x10\n" + + "\x03SKU\x18\x03 \x01(\x03R\x03SKU\x12\x16\n" + + "\x06source\x18\x04 \x01(\tR\x06source2{\n" + + "\x0fProductsService\x12h\n" + + "\x11GetListOfProducts\x12'.ozon.products.GetListOfProductsRequest\x1a(.ozon.products.GetListOfProductsResponse0\x01B\x11Z\x0f./ozon/productsb\x06proto3" + +var ( + file_ozon_products_proto_rawDescOnce sync.Once + file_ozon_products_proto_rawDescData []byte +) + +func file_ozon_products_proto_rawDescGZIP() []byte { + file_ozon_products_proto_rawDescOnce.Do(func() { + file_ozon_products_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ozon_products_proto_rawDesc), len(file_ozon_products_proto_rawDesc))) + }) + return file_ozon_products_proto_rawDescData +} + +var file_ozon_products_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_ozon_products_proto_goTypes = []any{ + (*GetListOfProductsRequest)(nil), // 0: ozon.products.GetListOfProductsRequest + (*GetListOfProductsResponse)(nil), // 1: ozon.products.GetListOfProductsResponse + (*Product)(nil), // 2: ozon.products.Product + (*Product_Status)(nil), // 3: ozon.products.Product.Status + (*Product_Stocks)(nil), // 4: ozon.products.Product.Stocks + (*Product_Stock)(nil), // 5: ozon.products.Product.Stock +} +var file_ozon_products_proto_depIdxs = []int32{ + 2, // 0: ozon.products.GetListOfProductsResponse.products:type_name -> ozon.products.Product + 4, // 1: ozon.products.Product.stocks:type_name -> ozon.products.Product.Stocks + 3, // 2: ozon.products.Product.statuses:type_name -> ozon.products.Product.Status + 5, // 3: ozon.products.Product.Stocks.stocks:type_name -> ozon.products.Product.Stock + 0, // 4: ozon.products.ProductsService.GetListOfProducts:input_type -> ozon.products.GetListOfProductsRequest + 1, // 5: ozon.products.ProductsService.GetListOfProducts:output_type -> ozon.products.GetListOfProductsResponse + 5, // [5:6] is the sub-list for method output_type + 4, // [4:5] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_ozon_products_proto_init() } +func file_ozon_products_proto_init() { + if File_ozon_products_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_ozon_products_proto_rawDesc), len(file_ozon_products_proto_rawDesc)), + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_ozon_products_proto_goTypes, + DependencyIndexes: file_ozon_products_proto_depIdxs, + MessageInfos: file_ozon_products_proto_msgTypes, + }.Build() + File_ozon_products_proto = out.File + file_ozon_products_proto_goTypes = nil + file_ozon_products_proto_depIdxs = nil +} diff --git a/api/generated/v1/ozon/products/products_grpc.pb.go b/api/generated/v1/ozon/products/products_grpc.pb.go new file mode 100644 index 0000000..160e4b5 --- /dev/null +++ b/api/generated/v1/ozon/products/products_grpc.pb.go @@ -0,0 +1,126 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.0 +// source: ozon/products.proto + +package products + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// 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.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + ProductsService_GetListOfProducts_FullMethodName = "/ozon.products.ProductsService/GetListOfProducts" +) + +// ProductsServiceClient is the client API for ProductsService 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 ProductsServiceClient interface { + // Retrieves a list of products based on the provided request. + GetListOfProducts(ctx context.Context, in *GetListOfProductsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[GetListOfProductsResponse], error) +} + +type productsServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProductsServiceClient(cc grpc.ClientConnInterface) ProductsServiceClient { + return &productsServiceClient{cc} +} + +func (c *productsServiceClient) GetListOfProducts(ctx context.Context, in *GetListOfProductsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[GetListOfProductsResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ProductsService_ServiceDesc.Streams[0], ProductsService_GetListOfProducts_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[GetListOfProductsRequest, GetListOfProductsResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ProductsService_GetListOfProductsClient = grpc.ServerStreamingClient[GetListOfProductsResponse] + +// ProductsServiceServer is the server API for ProductsService service. +// All implementations must embed UnimplementedProductsServiceServer +// for forward compatibility. +type ProductsServiceServer interface { + // Retrieves a list of products based on the provided request. + GetListOfProducts(*GetListOfProductsRequest, grpc.ServerStreamingServer[GetListOfProductsResponse]) error + mustEmbedUnimplementedProductsServiceServer() +} + +// UnimplementedProductsServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedProductsServiceServer struct{} + +func (UnimplementedProductsServiceServer) GetListOfProducts(*GetListOfProductsRequest, grpc.ServerStreamingServer[GetListOfProductsResponse]) error { + return status.Errorf(codes.Unimplemented, "method GetListOfProducts not implemented") +} +func (UnimplementedProductsServiceServer) mustEmbedUnimplementedProductsServiceServer() {} +func (UnimplementedProductsServiceServer) testEmbeddedByValue() {} + +// UnsafeProductsServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProductsServiceServer will +// result in compilation errors. +type UnsafeProductsServiceServer interface { + mustEmbedUnimplementedProductsServiceServer() +} + +func RegisterProductsServiceServer(s grpc.ServiceRegistrar, srv ProductsServiceServer) { + // If the following call pancis, it indicates UnimplementedProductsServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&ProductsService_ServiceDesc, srv) +} + +func _ProductsService_GetListOfProducts_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(GetListOfProductsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ProductsServiceServer).GetListOfProducts(m, &grpc.GenericServerStream[GetListOfProductsRequest, GetListOfProductsResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type ProductsService_GetListOfProductsServer = grpc.ServerStreamingServer[GetListOfProductsResponse] + +// ProductsService_ServiceDesc is the grpc.ServiceDesc for ProductsService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProductsService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ozon.products.ProductsService", + HandlerType: (*ProductsServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "GetListOfProducts", + Handler: _ProductsService_GetListOfProducts_Handler, + ServerStreams: true, + }, + }, + Metadata: "ozon/products.proto", +} diff --git a/api/generated/v1/test.pb.go b/api/generated/v1/test.pb.go deleted file mode 100755 index 1f92a47..0000000 --- a/api/generated/v1/test.pb.go +++ /dev/null @@ -1,486 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.6 -// protoc v6.30.0 -// source: test.proto - -package v1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -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 CreateTestRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CreateTestRequest) Reset() { - *x = CreateTestRequest{} - mi := &file_test_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CreateTestRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateTestRequest) ProtoMessage() {} - -func (x *CreateTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateTestRequest.ProtoReflect.Descriptor instead. -func (*CreateTestRequest) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{0} -} - -func (x *CreateTestRequest) GetData() string { - if x != nil { - return x.Data - } - return "" -} - -type CreateTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CreateTestResponse) Reset() { - *x = CreateTestResponse{} - mi := &file_test_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CreateTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateTestResponse) ProtoMessage() {} - -func (x *CreateTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateTestResponse.ProtoReflect.Descriptor instead. -func (*CreateTestResponse) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{1} -} - -func (x *CreateTestResponse) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -type GetTestRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GetTestRequest) Reset() { - *x = GetTestRequest{} - mi := &file_test_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GetTestRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetTestRequest) ProtoMessage() {} - -func (x *GetTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetTestRequest.ProtoReflect.Descriptor instead. -func (*GetTestRequest) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{2} -} - -func (x *GetTestRequest) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -type GetTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GetTestResponse) Reset() { - *x = GetTestResponse{} - mi := &file_test_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GetTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetTestResponse) ProtoMessage() {} - -func (x *GetTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetTestResponse.ProtoReflect.Descriptor instead. -func (*GetTestResponse) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{3} -} - -func (x *GetTestResponse) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *GetTestResponse) GetData() string { - if x != nil { - return x.Data - } - return "" -} - -type UpdateTestRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UpdateTestRequest) Reset() { - *x = UpdateTestRequest{} - mi := &file_test_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UpdateTestRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateTestRequest) ProtoMessage() {} - -func (x *UpdateTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateTestRequest.ProtoReflect.Descriptor instead. -func (*UpdateTestRequest) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{4} -} - -func (x *UpdateTestRequest) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *UpdateTestRequest) GetData() string { - if x != nil { - return x.Data - } - return "" -} - -type UpdateTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UpdateTestResponse) Reset() { - *x = UpdateTestResponse{} - mi := &file_test_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UpdateTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateTestResponse) ProtoMessage() {} - -func (x *UpdateTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateTestResponse.ProtoReflect.Descriptor instead. -func (*UpdateTestResponse) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{5} -} - -func (x *UpdateTestResponse) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -type DeleteTestRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DeleteTestRequest) Reset() { - *x = DeleteTestRequest{} - mi := &file_test_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DeleteTestRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteTestRequest) ProtoMessage() {} - -func (x *DeleteTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[6] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteTestRequest.ProtoReflect.Descriptor instead. -func (*DeleteTestRequest) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{6} -} - -func (x *DeleteTestRequest) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -type DeleteTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DeleteTestResponse) Reset() { - *x = DeleteTestResponse{} - mi := &file_test_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DeleteTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteTestResponse) ProtoMessage() {} - -func (x *DeleteTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_test_proto_msgTypes[7] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteTestResponse.ProtoReflect.Descriptor instead. -func (*DeleteTestResponse) Descriptor() ([]byte, []int) { - return file_test_proto_rawDescGZIP(), []int{7} -} - -func (x *DeleteTestResponse) GetId() int64 { - if x != nil { - return x.Id - } - return 0 -} - -var File_test_proto protoreflect.FileDescriptor - -const file_test_proto_rawDesc = "" + - "\n" + - "\n" + - "test.proto\x12\x02v1\"'\n" + - "\x11CreateTestRequest\x12\x12\n" + - "\x04data\x18\x01 \x01(\tR\x04data\"$\n" + - "\x12CreateTestResponse\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\" \n" + - "\x0eGetTestRequest\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\"5\n" + - "\x0fGetTestResponse\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + - "\x04data\x18\x02 \x01(\tR\x04data\"7\n" + - "\x11UpdateTestRequest\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + - "\x04data\x18\x02 \x01(\tR\x04data\"$\n" + - "\x12UpdateTestResponse\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\"#\n" + - "\x11DeleteTestRequest\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\"$\n" + - "\x12DeleteTestResponse\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id2\xf8\x01\n" + - "\vTestService\x12;\n" + - "\n" + - "CreateTest\x12\x15.v1.CreateTestRequest\x1a\x16.v1.CreateTestResponse\x122\n" + - "\aGetTest\x12\x12.v1.GetTestRequest\x1a\x13.v1.GetTestResponse\x12;\n" + - "\n" + - "UpdateTest\x12\x15.v1.UpdateTestRequest\x1a\x16.v1.UpdateTestResponse\x12;\n" + - "\n" + - "DeleteTest\x12\x15.v1.DeleteTestRequest\x1a\x16.v1.DeleteTestResponseB\x14Z\x12./api/generated/v1b\x06proto3" - -var ( - file_test_proto_rawDescOnce sync.Once - file_test_proto_rawDescData []byte -) - -func file_test_proto_rawDescGZIP() []byte { - file_test_proto_rawDescOnce.Do(func() { - file_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_proto_rawDesc), len(file_test_proto_rawDesc))) - }) - return file_test_proto_rawDescData -} - -var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_test_proto_goTypes = []any{ - (*CreateTestRequest)(nil), // 0: v1.CreateTestRequest - (*CreateTestResponse)(nil), // 1: v1.CreateTestResponse - (*GetTestRequest)(nil), // 2: v1.GetTestRequest - (*GetTestResponse)(nil), // 3: v1.GetTestResponse - (*UpdateTestRequest)(nil), // 4: v1.UpdateTestRequest - (*UpdateTestResponse)(nil), // 5: v1.UpdateTestResponse - (*DeleteTestRequest)(nil), // 6: v1.DeleteTestRequest - (*DeleteTestResponse)(nil), // 7: v1.DeleteTestResponse -} -var file_test_proto_depIdxs = []int32{ - 0, // 0: v1.TestService.CreateTest:input_type -> v1.CreateTestRequest - 2, // 1: v1.TestService.GetTest:input_type -> v1.GetTestRequest - 4, // 2: v1.TestService.UpdateTest:input_type -> v1.UpdateTestRequest - 6, // 3: v1.TestService.DeleteTest:input_type -> v1.DeleteTestRequest - 1, // 4: v1.TestService.CreateTest:output_type -> v1.CreateTestResponse - 3, // 5: v1.TestService.GetTest:output_type -> v1.GetTestResponse - 5, // 6: v1.TestService.UpdateTest:output_type -> v1.UpdateTestResponse - 7, // 7: v1.TestService.DeleteTest:output_type -> v1.DeleteTestResponse - 4, // [4:8] is the sub-list for method output_type - 0, // [0:4] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_test_proto_init() } -func file_test_proto_init() { - if File_test_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_proto_rawDesc), len(file_test_proto_rawDesc)), - NumEnums: 0, - NumMessages: 8, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_test_proto_goTypes, - DependencyIndexes: file_test_proto_depIdxs, - MessageInfos: file_test_proto_msgTypes, - }.Build() - File_test_proto = out.File - file_test_proto_goTypes = nil - file_test_proto_depIdxs = nil -} diff --git a/api/generated/v1/test_grpc.pb.go b/api/generated/v1/test_grpc.pb.go deleted file mode 100755 index bc5ae5a..0000000 --- a/api/generated/v1/test_grpc.pb.go +++ /dev/null @@ -1,235 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc v6.30.0 -// source: test.proto - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// 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.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - TestService_CreateTest_FullMethodName = "/v1.TestService/CreateTest" - TestService_GetTest_FullMethodName = "/v1.TestService/GetTest" - TestService_UpdateTest_FullMethodName = "/v1.TestService/UpdateTest" - TestService_DeleteTest_FullMethodName = "/v1.TestService/DeleteTest" -) - -// TestServiceClient is the client API for TestService 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 TestServiceClient interface { - CreateTest(ctx context.Context, in *CreateTestRequest, opts ...grpc.CallOption) (*CreateTestResponse, error) - GetTest(ctx context.Context, in *GetTestRequest, opts ...grpc.CallOption) (*GetTestResponse, error) - UpdateTest(ctx context.Context, in *UpdateTestRequest, opts ...grpc.CallOption) (*UpdateTestResponse, error) - DeleteTest(ctx context.Context, in *DeleteTestRequest, opts ...grpc.CallOption) (*DeleteTestResponse, error) -} - -type testServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient { - return &testServiceClient{cc} -} - -func (c *testServiceClient) CreateTest(ctx context.Context, in *CreateTestRequest, opts ...grpc.CallOption) (*CreateTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(CreateTestResponse) - err := c.cc.Invoke(ctx, TestService_CreateTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *testServiceClient) GetTest(ctx context.Context, in *GetTestRequest, opts ...grpc.CallOption) (*GetTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(GetTestResponse) - err := c.cc.Invoke(ctx, TestService_GetTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *testServiceClient) UpdateTest(ctx context.Context, in *UpdateTestRequest, opts ...grpc.CallOption) (*UpdateTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(UpdateTestResponse) - err := c.cc.Invoke(ctx, TestService_UpdateTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *testServiceClient) DeleteTest(ctx context.Context, in *DeleteTestRequest, opts ...grpc.CallOption) (*DeleteTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(DeleteTestResponse) - err := c.cc.Invoke(ctx, TestService_DeleteTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// TestServiceServer is the server API for TestService service. -// All implementations must embed UnimplementedTestServiceServer -// for forward compatibility. -type TestServiceServer interface { - CreateTest(context.Context, *CreateTestRequest) (*CreateTestResponse, error) - GetTest(context.Context, *GetTestRequest) (*GetTestResponse, error) - UpdateTest(context.Context, *UpdateTestRequest) (*UpdateTestResponse, error) - DeleteTest(context.Context, *DeleteTestRequest) (*DeleteTestResponse, error) - mustEmbedUnimplementedTestServiceServer() -} - -// UnimplementedTestServiceServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedTestServiceServer struct{} - -func (UnimplementedTestServiceServer) CreateTest(context.Context, *CreateTestRequest) (*CreateTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateTest not implemented") -} -func (UnimplementedTestServiceServer) GetTest(context.Context, *GetTestRequest) (*GetTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetTest not implemented") -} -func (UnimplementedTestServiceServer) UpdateTest(context.Context, *UpdateTestRequest) (*UpdateTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateTest not implemented") -} -func (UnimplementedTestServiceServer) DeleteTest(context.Context, *DeleteTestRequest) (*DeleteTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteTest not implemented") -} -func (UnimplementedTestServiceServer) mustEmbedUnimplementedTestServiceServer() {} -func (UnimplementedTestServiceServer) testEmbeddedByValue() {} - -// UnsafeTestServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to TestServiceServer will -// result in compilation errors. -type UnsafeTestServiceServer interface { - mustEmbedUnimplementedTestServiceServer() -} - -func RegisterTestServiceServer(s grpc.ServiceRegistrar, srv TestServiceServer) { - // If the following call pancis, it indicates UnimplementedTestServiceServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&TestService_ServiceDesc, srv) -} - -func _TestService_CreateTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateTestRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).CreateTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: TestService_CreateTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).CreateTest(ctx, req.(*CreateTestRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _TestService_GetTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetTestRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).GetTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: TestService_GetTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).GetTest(ctx, req.(*GetTestRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _TestService_UpdateTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateTestRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).UpdateTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: TestService_UpdateTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).UpdateTest(ctx, req.(*UpdateTestRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _TestService_DeleteTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteTestRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServiceServer).DeleteTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: TestService_DeleteTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).DeleteTest(ctx, req.(*DeleteTestRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// TestService_ServiceDesc is the grpc.ServiceDesc for TestService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var TestService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "v1.TestService", - HandlerType: (*TestServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "CreateTest", - Handler: _TestService_CreateTest_Handler, - }, - { - MethodName: "GetTest", - Handler: _TestService_GetTest_Handler, - }, - { - MethodName: "UpdateTest", - Handler: _TestService_UpdateTest_Handler, - }, - { - MethodName: "DeleteTest", - Handler: _TestService_DeleteTest_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "test.proto", -} diff --git a/api/generated/v1/wb/products/products.pb.go b/api/generated/v1/wb/products/products.pb.go new file mode 100644 index 0000000..b9f6cb5 --- /dev/null +++ b/api/generated/v1/wb/products/products.pb.go @@ -0,0 +1,60 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.31.0 +// source: wb/products.proto + +package products + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + unsafe "unsafe" +) + +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) +) + +var File_wb_products_proto protoreflect.FileDescriptor + +const file_wb_products_proto_rawDesc = "" + + "\n" + + "\x11wb/products.proto\x12\vwb.products2\x11\n" + + "\x0fProductsServiceB\x0fZ\r./wb/productsb\x06proto3" + +var file_wb_products_proto_goTypes = []any{} +var file_wb_products_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_wb_products_proto_init() } +func file_wb_products_proto_init() { + if File_wb_products_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_wb_products_proto_rawDesc), len(file_wb_products_proto_rawDesc)), + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_wb_products_proto_goTypes, + DependencyIndexes: file_wb_products_proto_depIdxs, + }.Build() + File_wb_products_proto = out.File + file_wb_products_proto_goTypes = nil + file_wb_products_proto_depIdxs = nil +} diff --git a/api/generated/v1/wb/products/products_grpc.pb.go b/api/generated/v1/wb/products/products_grpc.pb.go new file mode 100644 index 0000000..357130f --- /dev/null +++ b/api/generated/v1/wb/products/products_grpc.pb.go @@ -0,0 +1,76 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.0 +// source: wb/products.proto + +package products + +import ( + grpc "google.golang.org/grpc" +) + +// 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.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +// ProductsServiceClient is the client API for ProductsService 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 ProductsServiceClient interface { +} + +type productsServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProductsServiceClient(cc grpc.ClientConnInterface) ProductsServiceClient { + return &productsServiceClient{cc} +} + +// ProductsServiceServer is the server API for ProductsService service. +// All implementations must embed UnimplementedProductsServiceServer +// for forward compatibility. +type ProductsServiceServer interface { + mustEmbedUnimplementedProductsServiceServer() +} + +// UnimplementedProductsServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedProductsServiceServer struct{} + +func (UnimplementedProductsServiceServer) mustEmbedUnimplementedProductsServiceServer() {} +func (UnimplementedProductsServiceServer) testEmbeddedByValue() {} + +// UnsafeProductsServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProductsServiceServer will +// result in compilation errors. +type UnsafeProductsServiceServer interface { + mustEmbedUnimplementedProductsServiceServer() +} + +func RegisterProductsServiceServer(s grpc.ServiceRegistrar, srv ProductsServiceServer) { + // If the following call pancis, it indicates UnimplementedProductsServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&ProductsService_ServiceDesc, srv) +} + +// ProductsService_ServiceDesc is the grpc.ServiceDesc for ProductsService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProductsService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "wb.products.ProductsService", + HandlerType: (*ProductsServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "wb/products.proto", +} diff --git a/api/generated/v1/yandexmarket/products/products.pb.go b/api/generated/v1/yandexmarket/products/products.pb.go new file mode 100644 index 0000000..f6e5d58 --- /dev/null +++ b/api/generated/v1/yandexmarket/products/products.pb.go @@ -0,0 +1,60 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.31.0 +// source: yandexmarket/products.proto + +package products + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + unsafe "unsafe" +) + +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) +) + +var File_yandexmarket_products_proto protoreflect.FileDescriptor + +const file_yandexmarket_products_proto_rawDesc = "" + + "\n" + + "\x1byandexmarket/products.proto\x12\x15yandexmarket.products2\x11\n" + + "\x0fProductsServiceB\x19Z\x17./yandexmarket/productsb\x06proto3" + +var file_yandexmarket_products_proto_goTypes = []any{} +var file_yandexmarket_products_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_yandexmarket_products_proto_init() } +func file_yandexmarket_products_proto_init() { + if File_yandexmarket_products_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_yandexmarket_products_proto_rawDesc), len(file_yandexmarket_products_proto_rawDesc)), + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_yandexmarket_products_proto_goTypes, + DependencyIndexes: file_yandexmarket_products_proto_depIdxs, + }.Build() + File_yandexmarket_products_proto = out.File + file_yandexmarket_products_proto_goTypes = nil + file_yandexmarket_products_proto_depIdxs = nil +} diff --git a/api/generated/v1/yandexmarket/products/products_grpc.pb.go b/api/generated/v1/yandexmarket/products/products_grpc.pb.go new file mode 100644 index 0000000..e597e88 --- /dev/null +++ b/api/generated/v1/yandexmarket/products/products_grpc.pb.go @@ -0,0 +1,76 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.0 +// source: yandexmarket/products.proto + +package products + +import ( + grpc "google.golang.org/grpc" +) + +// 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.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +// ProductsServiceClient is the client API for ProductsService 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 ProductsServiceClient interface { +} + +type productsServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProductsServiceClient(cc grpc.ClientConnInterface) ProductsServiceClient { + return &productsServiceClient{cc} +} + +// ProductsServiceServer is the server API for ProductsService service. +// All implementations must embed UnimplementedProductsServiceServer +// for forward compatibility. +type ProductsServiceServer interface { + mustEmbedUnimplementedProductsServiceServer() +} + +// UnimplementedProductsServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedProductsServiceServer struct{} + +func (UnimplementedProductsServiceServer) mustEmbedUnimplementedProductsServiceServer() {} +func (UnimplementedProductsServiceServer) testEmbeddedByValue() {} + +// UnsafeProductsServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProductsServiceServer will +// result in compilation errors. +type UnsafeProductsServiceServer interface { + mustEmbedUnimplementedProductsServiceServer() +} + +func RegisterProductsServiceServer(s grpc.ServiceRegistrar, srv ProductsServiceServer) { + // If the following call pancis, it indicates UnimplementedProductsServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&ProductsService_ServiceDesc, srv) +} + +// ProductsService_ServiceDesc is the grpc.ServiceDesc for ProductsService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProductsService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "yandexmarket.products.ProductsService", + HandlerType: (*ProductsServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "yandexmarket/products.proto", +} diff --git a/api/proto/v1 b/api/proto/v1 index ac37bf3..b30d322 160000 --- a/api/proto/v1 +++ b/api/proto/v1 @@ -1 +1 @@ -Subproject commit ac37bf36f5bc95cdcf145c89a48d4e0345ea2698 +Subproject commit b30d322774f089fc685bc184c39df1a0b3acfc5f diff --git a/cmd/server/main.go b/cmd/server/main.go index 6acdb1f..472df44 100755 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -1,118 +1,105 @@ package main import ( - adapters2 "Sipro-Marketplaces/internal/test/adapters" "context" - "database/sql" - "github.com/carlmjohnson/requests" - "log" - "os" - "os/signal" - "sync" - "syscall" - - "Sipro-Marketplaces/internal/config" - "Sipro-Marketplaces/internal/db" - "github.com/gofiber/fiber/v2" + "fmt" + "github.com/jackc/pgx/v5" + "github.com/joho/godotenv" "google.golang.org/grpc" + "net" + "os" + "sipro-mps/internal/marketplace" + ozon "sipro-mps/internal/ozon/products" + "sipro-mps/internal/redis" ) -type Server struct { - httpApp *fiber.App - grpcServer *grpc.Server - db *sql.DB +func logMessage(level string, format string, a ...interface{}) { + const ( + green = "\033[32m" + red = "\033[31m" + yellow = "\033[33m" + blue = "\033[34m" + reset = "\033[0m" + ) + switch level { + case "info": + fmt.Printf("%s✅ [INFO]%s %s %s\n", green, reset, fmt.Sprintf(format, a...), "ℹ️") + case "error": + fmt.Printf("%s❌ [ERROR]%s %s %s\n", red, reset, fmt.Sprintf(format, a...), "🚨") + default: + fmt.Printf("%s[LOG]%s %s\n", blue, reset, fmt.Sprintf(format, a...)) + } } -func NewServer(cfg config.Config) (*Server, error) { - dbConn, err := db.NewConnection(cfg.DB) - if err != nil { - return nil, err - } +func createGrpcServer() { - httpApp := fiber.New() - //adapters.RegisterHTTPRoutes(httpApp, testService) - kal := httpApp.Group("/test") - adapters2.RegisterRouter(&kal) + lis, err := net.Listen("tcp", ":8080") + if err != nil { + fmt.Printf("failed to listen: %v\n", err) + return + } grpcServer := grpc.NewServer() - return &Server{ - httpApp: httpApp, - grpcServer: grpcServer, - db: dbConn, - }, nil -} - -func (s *Server) Start(cfg config.Config) error { - var wg sync.WaitGroup - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - wg.Add(1) - go func() { - defer wg.Done() - log.Printf("Starting HTTP server on %s", cfg.HTTP) - if err := s.httpApp.Listen(cfg.HTTP); err != nil { - log.Printf("HTTP server failed: %v", err) - cancel() - } - }() - - wg.Add(1) - go func() { - defer wg.Done() - log.Printf("Starting gRPC server on %s", cfg.GRPC) - }() - - wg.Add(1) - - quit := make(chan os.Signal, 1) - signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) - select { - case <-quit: - log.Println("Shutting down...") - case <-ctx.Done(): - log.Println("Context cancelled, shutting down...") + repo, err := marketplace.RegisterAdapterGRPC(grpcServer) + if err != nil { + fmt.Printf("failed to register gRPC server: %v\n", err) + return + } + _, err = ozon.RegisterAdapterGRPC(grpcServer, *repo) + if err != nil { + fmt.Printf("failed to register Ozon Products gRPC server: %v\n", err) + return } - s.shutdown() - wg.Wait() - return nil -} + fmt.Println("gRPC server registered successfully.") + // Start serving gRPC requests + fmt.Println("gRPC server is starting on port 8080...") -func (s *Server) shutdown() { - log.Println("Initiating graceful shutdown...") - if err := s.httpApp.Shutdown(); err != nil { - log.Printf("Failed to stop HTTP: %v", err) + if err := grpcServer.Serve(lis); err != nil { + fmt.Printf("failed to serve: %v\n", err) } - s.grpcServer.GracefulStop() - if err := s.db.Close(); err != nil { - log.Printf("Failed to close DB: %v", err) - } - log.Println("Shutdown complete") + fmt.Println("gRPC server created.") } func main() { - type post struct { - Name string `json:"name"` - Language string `json:"language"` - ID string `json:"id"` - Bio string `json:"bio"` - Version float64 `json:"version"` - } - response := new([]post) - err := requests.URL("https://microsoftedge.github.io/Demos/json-dummy-data/5MB-min.json").ToJSON(&response).Fetch(context.Background()) + // Initializing the dotenv file + err := godotenv.Load() if err != nil { - log.Fatalf("Failed to fetch URL: %v", err) + logMessage("error", "Error loading .env file: %v", err) + return + } + logMessage("info", "Dotenv file loaded successfully. 🌱") - } - println(len(*response)) - return - cfg := config.Load() - server, err := NewServer(cfg) + ctx := context.Background() + + // Initializing the Redis client + err = redis.InitClient(ctx) if err != nil { - log.Fatalf("Failed to initialize server: %v", err) + logMessage("error", "Failed to initialize Redis client: %v", err) + return } - if err := server.Start(cfg); err != nil { - log.Fatalf("Server failed: %v", err) + defer redis.CloseClient() + logMessage("info", "Redis client initialized successfully. 🟥") + + // Initializing pgx connection + conn, err := pgx.Connect(ctx, os.Getenv("POSTGRES_URL")) + if err != nil { + logMessage("error", "Failed to connect to PostgreSQL: %v", err) + return } + defer conn.Close(ctx) + logMessage("info", "Connected to PostgreSQL successfully. 🐘") + createGrpcServer() + // ------------------ shitting + //mpRepo := marketplace.NewDBRepository(conn) + // + //productsRepo := products.NewAPIRepository( + // mpRepo) + //_, err = productsRepo.GetAllProducts(ctx, 262) + //if err != nil { + // return } + +//for _, item := range items { +// //logMessage("info", "Product ID: %s, Name: %s, Price: %d", item.Price, item.Name, item.Price) +//} diff --git a/generate_grpc.sh b/generate_grpc.sh index 1634d9e..1d9a2fc 100755 --- a/generate_grpc.sh +++ b/generate_grpc.sh @@ -1,6 +1,32 @@ #!/bin/bash + +set -e + +# Переход в репозиторий с proto-файлами +cd ./Sipro-Marketplaces-Protos + +# Коммит и пуш изменений, если они есть +if [[ -n $(git status --porcelain) ]]; then + git add . + git commit -m "Update proto definitions" + git push +else + echo "No changes to commit in Sipro-Marketplaces-Protos" +fi + +# Возврат в корень проекта +cd - + +# Пуллим обновления в /api/proto/v1 +cd ./api/proto/v1 +git pull +cd - + +# Генерация .pb.go файлов в папки согласно структуре .proto protoc \ - --go_out=paths=source_relative:./api/generated/v1 \ - --go-grpc_out=paths=source_relative:./api/generated/v1 \ + --go_out=./api/generated/v1 \ + --go-grpc_out=./api/generated/v1 \ -I./api/proto/v1 \ - ./api/proto/v1/*.proto + ./api/proto/v1/*/*.proto + +echo "Generation complete." diff --git a/go.mod b/go.mod index 374dd7e..5ae444d 100755 --- a/go.mod +++ b/go.mod @@ -1,51 +1,27 @@ -module Sipro-Marketplaces +module sipro-mps go 1.24 require ( - github.com/KyleBanks/depth v1.2.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/andybalholm/brotli v1.1.0 // indirect - github.com/bytedance/sonic v1.13.2 // indirect - github.com/bytedance/sonic/loader v0.2.4 // indirect - github.com/carlmjohnson/requests v0.24.3 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudwego/base64x v0.1.5 // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/spec v0.20.4 // indirect - github.com/go-openapi/swag v0.19.15 // indirect - github.com/gofiber/fiber/v2 v2.52.6 // indirect - github.com/gofiber/swagger v1.1.1 // indirect - github.com/golang-jwt/jwt/v5 v5.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.11 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/mailru/easyjson v0.7.6 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/redis/go-redis/v9 v9.7.3 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/rs/zerolog v1.34.0 // indirect - github.com/swaggo/files/v2 v2.0.2 // indirect - github.com/swaggo/swag v1.16.4 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/twmb/franz-go v1.18.1 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.51.0 // indirect - github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect - google.golang.org/grpc v1.71.1 // indirect - google.golang.org/protobuf v1.36.4 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + git.denco.store/fakz9/ozon-api-client v1.18.1-0.20250526003754-c6c303092505 + github.com/jackc/pgx/v5 v5.7.5 + github.com/joho/godotenv v1.5.1 + github.com/lib/pq v1.10.9 + github.com/redis/rueidis v1.0.60 + github.com/samber/lo v1.50.0 + github.com/tidwall/gjson v1.18.0 + google.golang.org/grpc v1.72.2 + google.golang.org/protobuf v1.36.5 +) + +require ( + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect ) diff --git a/go.sum b/go.sum index 212cd15..6bfa488 100755 --- a/go.sum +++ b/go.sum @@ -1,144 +1,79 @@ -github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= -github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= -github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= -github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= -github.com/carlmjohnson/requests v0.24.3 h1:LYcM/jVIVPkioigMjEAnBACXl2vb42TVqiC8EYNoaXQ= -github.com/carlmjohnson/requests v0.24.3/go.mod h1:duYA/jDnyZ6f3xbcF5PpZ9N8clgopubP2nK5i6MVMhU= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= -github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +git.denco.store/fakz9/ozon-api-client v1.18.1-0.20250526003754-c6c303092505 h1:5mviYMLXLIvsFEXLR0IlGuqMNzkB8X/yrmxZHYk0n84= +git.denco.store/fakz9/ozon-api-client v1.18.1-0.20250526003754-c6c303092505/go.mod h1:1uPm278HN7mDkP507KHsLpnW+R9vWGEzp9BSMycjVbQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI= -github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= -github.com/gofiber/swagger v1.1.1 h1:FZVhVQQ9s1ZKLHL/O0loLh49bYB5l1HEAgxDlcTtkRA= -github.com/gofiber/swagger v1.1.1/go.mod h1:vtvY/sQAMc/lGTUCg0lqmBL7Ht9O7uzChpbvJeJQINw= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +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/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= +github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= -github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= -github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/redis/rueidis v1.0.60 h1:MGZX8uNdw7iyWz22JhjA/9iXzddfCUE/EMK4VxKoKpA= +github.com/redis/rueidis v1.0.60/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA= +github.com/samber/lo v1.50.0 h1:XrG0xOeHs+4FQ8gJR97zDz5uOFMW7OwFWiFVzqopKgY= +github.com/samber/lo v1.50.0/go.mod h1:RjZyNk6WSnUFRKK6EyOhsRJMqft3G+pg7dCWHQCWvsc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/swaggo/files/v2 v2.0.2 h1:Bq4tgS/yxLB/3nwOMcul5oLEUKa877Ykgz3CJMVbQKU= -github.com/swaggo/files/v2 v2.0.2/go.mod h1:TVqetIzZsO9OhHX1Am9sRf9LdrFZqoK49N37KON/jr0= -github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A= -github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/twmb/franz-go v1.18.1 h1:D75xxCDyvTqBSiImFx2lkPduE39jz1vaD7+FNc+vMkc= -github.com/twmb/franz-go v1.18.1/go.mod h1:Uzo77TarcLTUZeLuGq+9lNpSkfZI+JErv7YJhlDjs9M= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= -google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= -google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= -google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +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.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +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.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/internal/db/sqlc.yaml b/internal/db/sqlc.yaml index f610c8b..2f4c3b4 100755 --- a/internal/db/sqlc.yaml +++ b/internal/db/sqlc.yaml @@ -2,6 +2,6 @@ version: "1" packages: - name: "test" path: "../test/db/generated" - queries: "../test/db/queries.sql" + queries: "../test/db/query.sql" schema: "./schema.sql" engine: "postgresql" \ No newline at end of file diff --git a/internal/marketplace/adapter_grpc.go b/internal/marketplace/adapter_grpc.go new file mode 100644 index 0000000..73209f5 --- /dev/null +++ b/internal/marketplace/adapter_grpc.go @@ -0,0 +1,46 @@ +package marketplace + +import ( + "context" + "github.com/jackc/pgx/v5" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + pb "sipro-mps/api/generated/v1/marketplace" +) + +// AdapterGRPC implements the gRPC server for the Marketplace service. +type AdapterGRPC struct { + pb.UnimplementedMarketplaceServiceServer + repo Repository +} + +func NewAdapterGRPC(repo Repository) *AdapterGRPC { + return &AdapterGRPC{ + repo: repo, + } +} +func RegisterAdapterGRPC(server *grpc.Server) (*Repository, error) { + conn, err := pgx.Connect(context.Background(), "postgresql://postgres:GjitkeYf%5Beq@/sipro?host=/run/postgresql") + if err != nil { + return nil, err + } + repo := NewDBRepository(conn) + adapter := NewAdapterGRPC(repo) + pb.RegisterMarketplaceServiceServer(server, adapter) + return &repo, nil +} + +func (g *AdapterGRPC) GetMarketplaceById(ctx context.Context, r *pb.GetMarketplaceByIdRequest) (*pb.Marketplace, error) { + mp, err := g.repo.GetMarketplaceByID(ctx, int(r.MarketplaceId)) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get marketplace by ID: %v", err) + } + + return &pb.Marketplace{ + Id: uint64(uint32(mp.ID)), + BaseMarketplace: uint32(int32(mp.BaseMarketplace)), + AuthData: mp.AuthData, + WarehouseId: mp.WarehouseID, + }, nil +} diff --git a/internal/marketplace/db/db.go b/internal/marketplace/db/db.go new file mode 100644 index 0000000..eeee39e --- /dev/null +++ b/internal/marketplace/db/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package db + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/marketplace/db/models.go b/internal/marketplace/db/models.go new file mode 100644 index 0000000..239c76c --- /dev/null +++ b/internal/marketplace/db/models.go @@ -0,0 +1,17 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 + +package db + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Marketplace struct { + ID int32 + BaseMarketplace int32 + Name string + AuthData pgtype.Text + WarehouseID pgtype.Text +} diff --git a/internal/marketplace/db/query.sql b/internal/marketplace/db/query.sql new file mode 100644 index 0000000..f13c8a4 --- /dev/null +++ b/internal/marketplace/db/query.sql @@ -0,0 +1,3 @@ +-- name: GetMarketplaceByID :one +SELECT * FROM marketplaces +WHERE id = $1 LIMIT 1; diff --git a/internal/marketplace/db/query.sql.go b/internal/marketplace/db/query.sql.go new file mode 100644 index 0000000..cafbe79 --- /dev/null +++ b/internal/marketplace/db/query.sql.go @@ -0,0 +1,28 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.28.0 +// source: query.sql + +package db + +import ( + "context" +) + +const getMarketplaceByID = `-- name: GetMarketplaceByID :one +SELECT id, base_marketplace, name, auth_data, warehouse_id FROM marketplaces +WHERE id = $1 LIMIT 1 +` + +func (q *Queries) GetMarketplaceByID(ctx context.Context, id int32) (Marketplace, error) { + row := q.db.QueryRow(ctx, getMarketplaceByID, id) + var i Marketplace + err := row.Scan( + &i.ID, + &i.BaseMarketplace, + &i.Name, + &i.AuthData, + &i.WarehouseID, + ) + return i, err +} diff --git a/internal/marketplace/db/schema.sql b/internal/marketplace/db/schema.sql new file mode 100644 index 0000000..ee22237 --- /dev/null +++ b/internal/marketplace/db/schema.sql @@ -0,0 +1,9 @@ +create table marketplaces +( + id serial + primary key, + base_marketplace integer not null, + name varchar not null, + auth_data varchar, + warehouse_id varchar +); \ No newline at end of file diff --git a/internal/marketplace/db/sqlc.yaml b/internal/marketplace/db/sqlc.yaml new file mode 100644 index 0000000..ed1e34f --- /dev/null +++ b/internal/marketplace/db/sqlc.yaml @@ -0,0 +1,10 @@ +version: 2 +sql: + - engine: "postgresql" + queries: "query.sql" + schema: "schema.sql" + gen: + go: + package: "db" + out: "." + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/marketplace/entities.go b/internal/marketplace/entities.go new file mode 100644 index 0000000..cae3fd3 --- /dev/null +++ b/internal/marketplace/entities.go @@ -0,0 +1,8 @@ +package marketplace + +type Marketplace struct { + ID int `json:"id"` + BaseMarketplace int `json:"base_marketplace"` + AuthData string `json:"auth_data"` + WarehouseID string `json:"warehouse_id"` +} diff --git a/internal/marketplace/repository.go b/internal/marketplace/repository.go new file mode 100644 index 0000000..8993cdb --- /dev/null +++ b/internal/marketplace/repository.go @@ -0,0 +1,8 @@ +package marketplace + +import "context" + +type Repository interface { + // GetMarketplaceByID retrieves a marketplace by its ID. + GetMarketplaceByID(ctx context.Context, id int) (*Marketplace, error) +} diff --git a/internal/marketplace/repository_db.go b/internal/marketplace/repository_db.go new file mode 100644 index 0000000..9bbea84 --- /dev/null +++ b/internal/marketplace/repository_db.go @@ -0,0 +1,29 @@ +package marketplace + +import ( + "context" + "github.com/jackc/pgx/v5" + "sipro-mps/internal/marketplace/db" +) + +type dbRepository struct { + conn *pgx.Conn +} + +func NewDBRepository(conn *pgx.Conn) Repository { + return &dbRepository{conn: conn} +} + +func (r *dbRepository) GetMarketplaceByID(ctx context.Context, id int) (*Marketplace, error) { + queries := db.New(r.conn) + marketplace, err := queries.GetMarketplaceByID(ctx, int32(id)) + if err != nil { + return nil, err + } + return &Marketplace{ + ID: int(marketplace.ID), + BaseMarketplace: int(marketplace.BaseMarketplace), + AuthData: marketplace.AuthData.String, + WarehouseID: marketplace.WarehouseID.String, + }, nil +} diff --git a/internal/ozon/common.go b/internal/ozon/common.go new file mode 100644 index 0000000..c11178c --- /dev/null +++ b/internal/ozon/common.go @@ -0,0 +1,35 @@ +package ozon + +import ( + "errors" + "git.denco.store/fakz9/ozon-api-client/ozon" + "github.com/tidwall/gjson" + "net/http" + "sipro-mps/internal/marketplace" +) + +func GetClientFromMarketplace(mp *marketplace.Marketplace) (*ozon.Client, error) { + + authDataParsed := gjson.Parse(mp.AuthData) + clientIdResult := authDataParsed.Get("clientId") + apiKeyResult := authDataParsed.Get("clientToken") + if !clientIdResult.Exists() || !apiKeyResult.Exists() { + return nil, errors.New("auth data is not valid") + } + apiKey := apiKeyResult.String() + clientId := clientIdResult.String() + httpClient := &http.Client{ + Transport: NewRateLimitTransport(), + } + opts := []ozon.ClientOption{ + ozon.WithAPIKey(apiKey), + ozon.WithClientId(clientId), + ozon.WithHttpClient(httpClient), + } + client := ozon.NewClient(opts...) + if client == nil { + return nil, errors.New("failed to create ozon client") + } + + return client, nil +} diff --git a/internal/ozon/products/adapter_grpc.go b/internal/ozon/products/adapter_grpc.go new file mode 100644 index 0000000..0f7f944 --- /dev/null +++ b/internal/ozon/products/adapter_grpc.go @@ -0,0 +1,62 @@ +package products + +import ( + "github.com/samber/lo" + "google.golang.org/grpc" + pb "sipro-mps/api/generated/v1/ozon/products" + "sipro-mps/internal/marketplace" + "sipro-mps/internal/ozon/products/mapping/generated" +) + +type AdapterGRPC struct { + pb.UnimplementedProductsServiceServer + repo Repository +} + +func NewAdapterGRPC(repo Repository) *AdapterGRPC { + return &AdapterGRPC{ + repo: repo, + } +} + +// RegisterAdapterGRPC registers the gRPC server for the Products service. +func RegisterAdapterGRPC(server *grpc.Server, marketplaceRepo marketplace.Repository) (repo *Repository, err error) { + apiRepo := NewAPIRepository(marketplaceRepo) + adapter := NewAdapterGRPC(apiRepo) + pb.RegisterProductsServiceServer(server, adapter) + return &apiRepo, nil +} + +func (g *AdapterGRPC) GetListOfProducts(req *pb.GetListOfProductsRequest, stream pb.ProductsService_GetListOfProductsServer) error { + ctx := stream.Context() + converter := generated.ConverterImpl{} + resultChan := make(chan []OzonProduct) + errChan := make(chan error) + g.repo.StreamAllProducts(ctx, 262, resultChan, errChan) + for { + select { + case <-ctx.Done(): + return ctx.Err() // Handle context cancellation + case products, ok := <-resultChan: + if !ok { + return nil + } + protoProducts := lo.Map(products, func(product OzonProduct, _ int) *pb.Product { + return converter.ToProto(&product) + }) + resp := &pb.GetListOfProductsResponse{ + Products: protoProducts, + } + if err := stream.Send(resp); err != nil { + return err // Error sending response + } + case err, ok := <-errChan: + if !ok { + return nil // Exit loop when errChan is closed + } + if err != nil { + return err + } + } + } +} diff --git a/internal/ozon/products/entities.go b/internal/ozon/products/entities.go new file mode 100644 index 0000000..29210a1 --- /dev/null +++ b/internal/ozon/products/entities.go @@ -0,0 +1,5 @@ +package products + +import "git.denco.store/fakz9/ozon-api-client/ozon" + +type OzonProduct = ozon.ProductDetails diff --git a/internal/ozon/products/mapping/converter.go b/internal/ozon/products/mapping/converter.go new file mode 100644 index 0000000..7bbf3ff --- /dev/null +++ b/internal/ozon/products/mapping/converter.go @@ -0,0 +1,20 @@ +package mapping + +import ( + internal "git.denco.store/fakz9/ozon-api-client/ozon" + proto "sipro-mps/api/generated/v1/ozon/products" +) + +//go:generate go run github.com/jmattheis/goverter/cmd/goverter gen -g 'ignoreUnexported yes' . + +// goverter:converter +// goverter:extend Int632ToInt64 +type Converter interface { + // goverter:ignore state sizeCache unknownFields + + ToProto(details *internal.ProductDetails) *proto.Product +} + +func Int632ToInt64(i int32) int64 { + return int64(i) +} diff --git a/internal/ozon/products/mapping/generated/generated.go b/internal/ozon/products/mapping/generated/generated.go new file mode 100644 index 0000000..30dfc06 --- /dev/null +++ b/internal/ozon/products/mapping/generated/generated.go @@ -0,0 +1,56 @@ +// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. +//go:build !goverter + +package generated + +import ( + ozon "git.denco.store/fakz9/ozon-api-client/ozon" + + products "sipro-mps/api/generated/v1/ozon/products" + ozon "git.denco.store/fakz9/ozon-api-client/ozon" +) + +type ConverterImpl struct{} + +func (c *ConverterImpl) ToProto(source *ozon.ProductDetails) *products.Product { + var pProductsProduct *products.Product + if source != nil { + var productsProduct products.Product + productsProduct.Id = (*source).Id + productsProduct.OfferId = (*source).OfferId + productsProduct.Stocks = c.ozonProductDetailStockToPProductsProduct_Stocks((*source).Stocks) + if (*source).Barcodes != nil { + productsProduct.Barcodes = make([]string, len((*source).Barcodes)) + for i := 0; i < len((*source).Barcodes); i++ { + productsProduct.Barcodes[i] = (*source).Barcodes[i] + } + } + productsProduct.Statuses = c.ozonProductDetailsStatusToPProductsProduct_Status((*source).Statuses) + pProductsProduct = &productsProduct + } + return pProductsProduct +} +func (c *ConverterImpl) ozonProductDetailStockStockToPProductsProduct_Stock(source ozon.ProductDetailStockStock) *products.Product_Stock { + var productsProduct_Stock products.Product_Stock + productsProduct_Stock.Present = mapping.Int632ToInt64(source.Present) + productsProduct_Stock.Reserved = mapping.Int632ToInt64(source.Reserved) + productsProduct_Stock.SKU = source.SKU + productsProduct_Stock.Source = source.Source + return &productsProduct_Stock +} +func (c *ConverterImpl) ozonProductDetailStockToPProductsProduct_Stocks(source ozon.ProductDetailStock) *products.Product_Stocks { + var productsProduct_Stocks products.Product_Stocks + if source.Stocks != nil { + productsProduct_Stocks.Stocks = make([]*products.Product_Stock, len(source.Stocks)) + for i := 0; i < len(source.Stocks); i++ { + productsProduct_Stocks.Stocks[i] = c.ozonProductDetailStockStockToPProductsProduct_Stock(source.Stocks[i]) + } + } + productsProduct_Stocks.HasStock = source.HasStock + return &productsProduct_Stocks +} +func (c *ConverterImpl) ozonProductDetailsStatusToPProductsProduct_Status(source ozon.ProductDetailsStatus) *products.Product_Status { + var productsProduct_Status products.Product_Status + productsProduct_Status.StatusName = source.StatusName + return &productsProduct_Status +} diff --git a/internal/ozon/products/repository.go b/internal/ozon/products/repository.go new file mode 100644 index 0000000..d4a5cf2 --- /dev/null +++ b/internal/ozon/products/repository.go @@ -0,0 +1,8 @@ +package products + +import "context" + +type Repository interface { + GetAllProducts(ctx context.Context, marketplaceId int) ([]OzonProduct, error) + StreamAllProducts(ctx context.Context, marketplaceId int, resultChan chan<- []OzonProduct, errChan chan<- error) +} diff --git a/internal/ozon/products/repository_api.go b/internal/ozon/products/repository_api.go new file mode 100644 index 0000000..988995a --- /dev/null +++ b/internal/ozon/products/repository_api.go @@ -0,0 +1,118 @@ +package products + +import ( + "context" + "fmt" + api "git.denco.store/fakz9/ozon-api-client/ozon" + "github.com/samber/lo" + "sipro-mps/internal/marketplace" + "sipro-mps/internal/ozon" + "sync" +) + +type apiRepository struct { + marketplaceRepository marketplace.Repository +} + +func NewAPIRepository(marketplaceRepository marketplace.Repository) Repository { + return &apiRepository{ + marketplaceRepository: marketplaceRepository, + } +} + +func fetchProductIds(ctx context.Context, client *api.Client, resultChan chan<- []int64, errChan chan<- error) { + defer close(resultChan) + lastId := "" + for { + resp, err := client.Products().GetListOfProducts(ctx, &api.GetListOfProductsParams{ + Filter: api.GetListOfProductsFilter{Visibility: "ALL"}, + LastId: lastId, + Limit: 1000, + }) + if err != nil { + // dev + panic(err) + //errChan <- fmt.Errorf("fetching product IDs: %w", err) + return + } + + items := resp.Result.Items + if len(items) == 0 { + break + } + productIds := lo.Map(items, func(item api.GetListOfProductsResultItem, _ int) int64 { return item.ProductId }) + + resultChan <- productIds + + lastId = resp.Result.LastId + if lastId == "" { + break + } + } +} + +func fetchProducts(ctx context.Context, client *api.Client, productIdsChan <-chan []int64, resultChan chan<- []OzonProduct, errChan chan<- error) { + defer close(resultChan) + defer close(errChan) + wg := sync.WaitGroup{} + + for productIds := range productIdsChan { + wg.Add(1) + go func() { + defer wg.Done() + resp, err := client.Products().ListProductsByIDs(ctx, &api.ListProductsByIDsParams{ + ProductId: productIds, + }) + if err != nil { + // dev + panic(err) + //errChan <- fmt.Errorf("fetching products: %w", err) + return + } + items := resp.Items + resultChan <- items + }() + } + wg.Wait() +} + +func (a *apiRepository) GetAllProducts(ctx context.Context, marketplaceId int) ([]OzonProduct, error) { + mp, err := a.marketplaceRepository.GetMarketplaceByID(ctx, marketplaceId) + if err != nil { + return nil, err + } + client, err := ozon.GetClientFromMarketplace(mp) + if err != nil { + return nil, err + } + items := []OzonProduct{} + productIdsChan := make(chan []int64) + producsChan := make(chan []OzonProduct) + errChan := make(chan error) + go fetchProductIds(ctx, client, productIdsChan, errChan) + go fetchProducts(ctx, client, productIdsChan, producsChan, errChan) + for products := range producsChan { + for _, product := range products { + fmt.Println(product.Name) + items = append(items, product) + } + } + fmt.Println(len(items)) + return items, nil +} + +func (a *apiRepository) StreamAllProducts(ctx context.Context, marketplaceId int, resultChan chan<- []OzonProduct, errChan chan<- error) { + mp, err := a.marketplaceRepository.GetMarketplaceByID(ctx, marketplaceId) + if err != nil { + errChan <- err + return + } + client, err := ozon.GetClientFromMarketplace(mp) + if err != nil { + errChan <- err + return + } + productIdsChan := make(chan []int64) + go fetchProductIds(ctx, client, productIdsChan, errChan) + go fetchProducts(ctx, client, productIdsChan, resultChan, errChan) +} diff --git a/internal/ozon/rate_limiter.go b/internal/ozon/rate_limiter.go new file mode 100644 index 0000000..4f7e9af --- /dev/null +++ b/internal/ozon/rate_limiter.go @@ -0,0 +1,67 @@ +package ozon + +import ( + "fmt" + "github.com/redis/rueidis" + "net/http" + "sipro-mps/internal/redis" + "time" +) + +const ( + windowSize = time.Second + rps = 50 // requests per second +) + +var ( + rateLimiterScript = rueidis.NewLuaScript(` + local key = KEYS[1] + local now = tonumber(ARGV[1]) + local window = tonumber(ARGV[2]) + local limit = tonumber(ARGV[3]) + + -- Удаляем старые записи вне окна времени + redis.call('ZREMRANGEBYSCORE', key, '-inf', now - window) + local count = redis.call('ZCARD', key) + + if count < limit then + -- Лимит не превышен, добавляем новую метку и устанавливаем TTL + redis.call('ZADD', key, now, now) + redis.call('EXPIRE', key, math.ceil(window / 1000000000)) + return 0 -- Можно выполнять запрос сразу + else + -- Лимит превышен, находим самую старую метку + local oldest = redis.call('ZRANGE', key, 0, 0, 'WITHSCORES')[2] + -- Возвращаем время, которое нужно подождать до освобождения слота + return (tonumber(oldest) + window) - now + end + `) +) + +type RateLimitTransport struct { + http.RoundTripper +} + +func (t *RateLimitTransport) RoundTrip(req *http.Request) (*http.Response, error) { + fmt.Println(time.Now().Format("2006-01-02 15:04:05")) + ctx := req.Context() + clientId := req.Header.Get("Client-Id") + now := time.Now().UnixNano() + + waitTime, err := rateLimiterScript.Exec(ctx, *redis.Client, []string{clientId}, []string{ + fmt.Sprintf("%d", now), + fmt.Sprintf("%d", int64(windowSize)), + fmt.Sprintf("%d", 50), + }).ToInt64() + if err != nil { + return nil, fmt.Errorf("failed to execute rate limit script: %w", err) + } + if waitTime > 0 { + time.Sleep(time.Duration(waitTime)) + } + return t.RoundTripper.RoundTrip(req) +} +func NewRateLimitTransport() *RateLimitTransport { + + return &RateLimitTransport{RoundTripper: http.DefaultTransport} +} diff --git a/internal/redis/client.go b/internal/redis/client.go new file mode 100644 index 0000000..02c9833 --- /dev/null +++ b/internal/redis/client.go @@ -0,0 +1,36 @@ +package redis + +import ( + "context" + "github.com/redis/rueidis" + "os" +) + +var Client *rueidis.Client + +func InitClient(ctx context.Context) error { + var err error + host := os.Getenv("REDIS_HOST") + port := os.Getenv("REDIS_PORT") + password := os.Getenv("REDIS_PASSWORD") + + client, err := rueidis.NewClient(rueidis.ClientOption{ + InitAddress: []string{host + ":" + port}, + Password: password, + }) + if err != nil { + return err + } + err = client.Do(ctx, client.B().Ping().Build()).Error() + if err != nil { + return err + } + Client = &client + return nil +} + +func CloseClient() { + if Client != nil { + (*Client).Close() + } +} diff --git a/internal/test/adapters/http.go b/internal/test/adapters/http.go deleted file mode 100755 index 5112623..0000000 --- a/internal/test/adapters/http.go +++ /dev/null @@ -1,19 +0,0 @@ -package adapters - -import "github.com/gofiber/fiber/v2" - -var ( - router *fiber.Router = nil -) - -func RegisterRouter(r *fiber.Router) { - router = r - if router == nil { - panic("router is nil") - } - (*router).Get("/test", test) -} - -func test(c *fiber.Ctx) error { - return c.SendString("test") -} diff --git a/internal/test/db/generated/db.go b/internal/test/db/generated/db.go deleted file mode 100755 index 4380e80..0000000 --- a/internal/test/db/generated/db.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.28.0 - -package test - -import ( - "context" - "database/sql" -) - -type DBTX interface { - ExecContext(context.Context, string, ...interface{}) (sql.Result, error) - PrepareContext(context.Context, string) (*sql.Stmt, error) - QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) - QueryRowContext(context.Context, string, ...interface{}) *sql.Row -} - -func New(db DBTX) *Queries { - return &Queries{db: db} -} - -type Queries struct { - db DBTX -} - -func (q *Queries) WithTx(tx *sql.Tx) *Queries { - return &Queries{ - db: tx, - } -} diff --git a/internal/test/db/generated/models.go b/internal/test/db/generated/models.go deleted file mode 100755 index 1273572..0000000 --- a/internal/test/db/generated/models.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.28.0 - -package test - -type Test struct { - ID int32 - Data string -} diff --git a/internal/test/db/generated/queries.sql.go b/internal/test/db/generated/queries.sql.go deleted file mode 100755 index 5c9d38f..0000000 --- a/internal/test/db/generated/queries.sql.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.28.0 -// source: queries.sql - -package test - -import ( - "context" -) - -const createTest = `-- name: CreateTest :one -INSERT INTO test (data) VALUES ($1) RETURNING id -` - -func (q *Queries) CreateTest(ctx context.Context, data string) (int32, error) { - row := q.db.QueryRowContext(ctx, createTest, data) - var id int32 - err := row.Scan(&id) - return id, err -} - -const deleteTest = `-- name: DeleteTest :exec -DELETE FROM test WHERE id = $1 -` - -func (q *Queries) DeleteTest(ctx context.Context, id int32) error { - _, err := q.db.ExecContext(ctx, deleteTest, id) - return err -} - -const getTest = `-- name: GetTest :one -SELECT id, data FROM test WHERE id = $1 -` - -func (q *Queries) GetTest(ctx context.Context, id int32) (Test, error) { - row := q.db.QueryRowContext(ctx, getTest, id) - var i Test - err := row.Scan(&i.ID, &i.Data) - return i, err -} - -const updateTest = `-- name: UpdateTest :exec -UPDATE test SET data = $1 WHERE id = $2 -` - -type UpdateTestParams struct { - Data string - ID int32 -} - -func (q *Queries) UpdateTest(ctx context.Context, arg UpdateTestParams) error { - _, err := q.db.ExecContext(ctx, updateTest, arg.Data, arg.ID) - return err -} diff --git a/internal/test/db/queries.sql b/internal/test/db/queries.sql deleted file mode 100755 index 6897148..0000000 --- a/internal/test/db/queries.sql +++ /dev/null @@ -1,11 +0,0 @@ --- name: CreateTest :one -INSERT INTO test (data) VALUES ($1) RETURNING id; - --- name: GetTest :one -SELECT id, data FROM test WHERE id = $1; - --- name: UpdateTest :exec -UPDATE test SET data = $1 WHERE id = $2; - --- name: DeleteTest :exec -DELETE FROM test WHERE id = $1; \ No newline at end of file diff --git a/internal/test/repository.go b/internal/test/repository.go deleted file mode 100755 index 7dd791f..0000000 --- a/internal/test/repository.go +++ /dev/null @@ -1,42 +0,0 @@ -package test - -import ( - generated "Sipro-Marketplaces/internal/test/db/generated" - "context" - "database/sql" -) - -type Repository interface { - Create(ctx context.Context, data string) (int32, error) - Get(ctx context.Context, id int32) (generated.Test, error) - Update(ctx context.Context, id int32, data string) error - Delete(ctx context.Context, id int32) error -} - -type repository struct { - db *sql.DB - queries *generated.Queries -} - -func NewRepository(db *sql.DB) Repository { - return &repository{ - db: db, - queries: generated.New(db), - } -} - -func (r *repository) Create(ctx context.Context, data string) (int32, error) { - return r.queries.CreateTest(ctx, data) -} - -func (r *repository) Get(ctx context.Context, id int32) (generated.Test, error) { - return r.queries.GetTest(ctx, id) -} - -func (r *repository) Update(ctx context.Context, id int32, data string) error { - return r.queries.UpdateTest(ctx, generated.UpdateTestParams{Data: data, ID: id}) -} - -func (r *repository) Delete(ctx context.Context, id int32) error { - return r.queries.DeleteTest(ctx, id) -} diff --git a/internal/test/service.go b/internal/test/service.go deleted file mode 100755 index bd4a891..0000000 --- a/internal/test/service.go +++ /dev/null @@ -1,37 +0,0 @@ -package test - -import ( - generated "Sipro-Marketplaces/internal/test/db/generated" - "context" -) - -type Service interface { - Create(ctx context.Context, data string) (int32, error) - Get(ctx context.Context, id int32) (generated.Test, error) - Update(ctx context.Context, id int32, data string) error - Delete(ctx context.Context, id int32) error -} - -type service struct { - repo Repository -} - -func NewService(repo Repository) Service { - return &service{repo: repo} -} - -func (s *service) Create(ctx context.Context, data string) (int32, error) { - return s.repo.Create(ctx, data) -} - -func (s *service) Get(ctx context.Context, id int32) (generated.Test, error) { - return s.repo.Get(ctx, id) -} - -func (s *service) Update(ctx context.Context, id int32, data string) error { - return s.repo.Update(ctx, id, data) -} - -func (s *service) Delete(ctx context.Context, id int32) error { - return s.repo.Delete(ctx, id) -} diff --git a/щдв b/щдв new file mode 100644 index 0000000..d9da9fa --- /dev/null +++ b/щдв @@ -0,0 +1,225 @@ +////// import ( +////// +////// "Sipro-Marketplaces/internal/marketplace" +////// ozon_products "Sipro-Marketplaces/internal/ozon/products" +////// "fmt" +////// "google.golang.org/grpc" +////// "net" +////// +////// ) +////// +////// func createGrpcServer() { +////// +////// lis, err := net.Listen("tcp", ":8080") +////// if err != nil { +////// fmt.Printf("failed to listen: %v\n", err) +////// return +////// } +////// grpcServer := grpc.NewServer() +////// +////// repo, err := marketplace.RegisterAdapterGRPC(grpcServer) +////// if err != nil { +////// fmt.Printf("failed to register gRPC server: %v\n", err) +////// return +////// } +////// _, err = ozon_products.RegisterAdapterGRPC(grpcServer, *repo) +////// if err != nil { +////// fmt.Printf("failed to register Ozon Products gRPC server: %v\n", err) +////// return +////// } +////// +////// fmt.Println("gRPC server registered successfully.") +////// // Start serving gRPC requests +////// fmt.Println("gRPC server is starting on port 8080...") +////// +////// if err := grpcServer.Serve(lis); err != nil { +////// fmt.Printf("failed to serve: %v\n", err) +////// } +////// fmt.Println("gRPC server created.") +////// } +////// +////// func main() { +////// fmt.Println("Starting Sipro-Marketplaces server...") +////// createGrpcServer() +////// } +////package main +//// +////import ( +//// "Sipro-Marketplaces/internal/marketplace" +//// "Sipro-Marketplaces/internal/ozon" +//// "context" +//// "encoding/json" +//// "fmt" +//// api "git.denco.store/fakz9/ozon-api-client/ozon" +//// "github.com/jackc/pgx/v5" +//// "time" +////) +//// +////func main() { +//// +//// startTime := time.Now() +//// +//// ctx := context.Background() +//// +//// conn, err := pgx.Connect(ctx, "postgresql://postgres:GjitkeYf%5Beq@/sipro?host=/run/postgresql") +//// if err != nil { +//// panic(err) +//// } +//// defer conn.Close(ctx) +//// mpRepo := marketplace.NewDBRepository(conn) +//// mp, err := mpRepo.GetMarketplaceByID(ctx, 262) +//// if err != nil { +//// panic(err) +//// } +//// client, err := ozon.GetClientFromMarketplace(mp) +//// if err != nil { +//// panic(err) +//// } +//// +//// productIdsChan := make(chan []int64) +//// +//// go func() { +//// defer close(productIdsChan) +//// +//// var lastId string +//// +//// for { +//// rsp, err := client.Products().GetListOfProducts( +//// ctx, +//// &api.GetListOfProductsParams{ +//// Filter: api.GetListOfProductsFilter{ +//// Visibility: "ALL", +//// }, +//// LastId: lastId, +//// Limit: 1000, +//// }, +//// ) +//// if err != nil { +//// // You may want to send error on another channel or handle differently +//// panic(err) +//// } +//// +//// items := rsp.Result.Items +//// if len(items) == 0 { +//// break +//// } +//// +//// productIds := make([]int64, len(items)) +//// for i, item := range items { +//// productIds[i] = item.ProductId +//// } +//// +//// productIdsChan <- productIds +//// +//// lastId = rsp.Result.LastId +//// if lastId == "" { +//// break +//// } +//// } +//// }() +//// +//// productsChan := make(chan []string) +//// go func() { +//// defer close(productsChan) +//// for productIds := range productIdsChan { +//// go func(ids []int64) { +//// products, err := client.Products().ListProductsByIDs( +//// ctx, &api.ListProductsByIDsParams{ +//// OfferId: nil, +//// ProductId: ids, +//// SKU: nil, +//// }) +//// if err != nil { +//// // Handle error appropriately, e.g., log it or send it to an error channel +//// panic(err) +//// } +//// productsEncoded := make([]string, len(products.Items)) +//// for i, product := range products.Items { +//// jsonString, err := json.Marshal(product) +//// if err != nil { +//// // Handle error appropriately, e.g., log it or send it to an error channel +//// panic(err) +//// } +//// productsEncoded[i] = string(jsonString) +//// } +//// productsChan <- productsEncoded +//// }(productIds) +//// } +//// +//// }() +//// total := 0 +//// for products := range productsChan { +//// for _ = range products { +//// // Here you can process each product, e.g., save to database or print +//// // For demonstration, we will just print the product +//// total += 1 +//// } +//// if len(products) == 0 { +//// fmt.Println("No more products to process.") +//// break +//// } +//// } +//// elapsedTime := time.Since(startTime) +//// println("Total time taken:", elapsedTime.String()) +//// println("Total products processed:", total) +//// +////} +// +//package main +// +//import ( +// "context" +// "fmt" +// "time" +// +// "github.com/redis/rueidis" +//) +// +//func main() { +// fmt.Println("Hello, World!") +// client, err := rueidis.NewClient(rueidis.ClientOption{ +// InitAddress: []string{"localhost:6379"}, +// Password: "ELdhsgqJt5QZUSWKU5vY3D9CXa1a0teIceeHqvCtoPkrDJ0Lge7XIe8187gFjd0qZLv9zwhGr62MqY", +// }) +// if err != nil { +// fmt.Printf("Failed to create Redis client: %v\n", err) +// return +// } +// defer client.Close() +// script := rueidis.NewLuaScript(` +// local key = KEYS[1] +// local now = tonumber(ARGV[1]) +// local window = tonumber(ARGV[2]) +// local limit = tonumber(ARGV[3]) +// +// redis.call('ZREMRANGEBYSCORE', key, '-inf', now - window) +// local count = redis.call('ZCARD', key) +// +// if count < limit then +// redis.call('ZADD', key, now, now) +// redis.call('EXPIRE', key, math.ceil(window / 1000000000)) +// return 1 +// end +// return 0 +// `) +// ctx := context.Background() +// windowSize := time.Second +// for i := 0; i < 51; i++ { +// now := time.Now().UnixNano() +// result, err := script.Exec(ctx, client, []string{"2282"}, []string{ +// fmt.Sprintf("%d", now), +// fmt.Sprintf("%d", int64(windowSize)), +// fmt.Sprintf("%d", 50), +// }).ToInt64() +// if err != nil { +// fmt.Printf("Failed to execute script: %v\n", err) +// return +// } +// if result == 1 { +// //fmt.Println("Request allowed") +// } else { +// fmt.Println("Rate limit exceeded") +// } +// } +// +//} \ No newline at end of file