From 489c9220e466cf2008499e12d32a8d5c79474a7d Mon Sep 17 00:00:00 2001 From: Andrew Tate Date: Thu, 6 Apr 2023 10:32:59 -0400 Subject: [PATCH 1/4] add new rest service --- src/restservice/.dockerignore | 1 + src/restservice/Dockerfile | 19 + src/restservice/README.md | 95 + src/restservice/demo/msdemo/demo.pb.go | 2645 +++++++++++++++++++ src/restservice/demo/msdemo/demo_grpc.pb.go | 1027 +++++++ src/restservice/genproto.sh | 7 + src/restservice/go.mod | 31 + src/restservice/go.sum | 197 ++ src/restservice/main.go | 150 ++ src/restservice/money/money.go | 117 + src/restservice/money/money_test.go | 231 ++ 11 files changed, 4520 insertions(+) create mode 100644 src/restservice/.dockerignore create mode 100644 src/restservice/Dockerfile create mode 100644 src/restservice/README.md create mode 100644 src/restservice/demo/msdemo/demo.pb.go create mode 100644 src/restservice/demo/msdemo/demo_grpc.pb.go create mode 100755 src/restservice/genproto.sh create mode 100644 src/restservice/go.mod create mode 100644 src/restservice/go.sum create mode 100644 src/restservice/main.go create mode 100644 src/restservice/money/money.go create mode 100644 src/restservice/money/money_test.go diff --git a/src/restservice/.dockerignore b/src/restservice/.dockerignore new file mode 100644 index 0000000..48b8bf9 --- /dev/null +++ b/src/restservice/.dockerignore @@ -0,0 +1 @@ +vendor/ diff --git a/src/restservice/Dockerfile b/src/restservice/Dockerfile new file mode 100644 index 0000000..03f4438 --- /dev/null +++ b/src/restservice/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.17-alpine as builder +RUN apk add --no-cache ca-certificates git +WORKDIR /src + +# restore dependencies +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN go build -gcflags='-N -l' -o /restservice . + +FROM alpine as release +RUN apk add --no-cache ca-certificates +#RUN GRPC_HEALTH_PROBE_VERSION=v0.3.6 && \ +# wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ +# chmod +x /bin/grpc_health_probe +COPY --from=builder /restservice /restservice +EXPOSE 5051 +ENTRYPOINT ["/restservice"] diff --git a/src/restservice/README.md b/src/restservice/README.md new file mode 100644 index 0000000..cb7d7b4 --- /dev/null +++ b/src/restservice/README.md @@ -0,0 +1,95 @@ +# checkout service + +The **checkout** service provides cart management, and order placement functionality. + +## OpenTelemetry instrumentation + +### Initialization +The OpenTelemetry SDK is initialized in `main` using the `initOtelTracing` function +``` +func initOtelTracing(ctx context.Context, log logrus.FieldLogger) *sdktrace.TracerProvider { + endpoint := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") + if endpoint == "" { + endpoint = "opentelemetry-collector:4317" + } + + // Set GRPC options to establish an insecure connection to an OpenTelemetry Collector + // To establish a TLS connection to a secured endpoint use: + // otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")) + opts := []otlptracegrpc.Option{ + otlptracegrpc.WithEndpoint(endpoint), + otlptracegrpc.WithInsecure(), + } + + // Create the exporter + exporter, err := otlptrace.New(ctx, otlptracegrpc.NewClient(opts...)) + if err != nil { + log.Fatal(err) + } + + // Specify the TextMapPropagator to ensure spans propagate across service boundaries + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})) + + // Set standard attributes per semantic conventions + res := resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String("checkout"), + ) + + // Create and set the TraceProvider + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(res), + ) + otel.SetTracerProvider(tp) + + return tp +} +``` + +You should call `TraceProvider.shutdown()` when your service is shutdown to ensure all spans are exported. +This service makes that call as part of a deferred function in `main` +``` + // Initialize OpenTelemetry Tracing + ctx := context.Background() + tp := initOtelTracing(ctx, log) + defer func() { _ = tp.Shutdown(ctx) }() +``` + +### gRPC instrumentation +This service receives gRPC requests, which are instrumented in the `main` function as part of the gRPC server creation. +``` + // create gRPC server with OpenTelemetry instrumentation on all incoming requests + srv := grpc.NewServer( + grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))), + grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))), + ) +``` + +This service will issue several outgoing gRPC calls, which are all instrumented within their respective handlers. +```go + // add OpenTelemetry instrumentation to outgoing gRPC requests + conn, err := grpc.DialContext(ctx, cs.shippingSvcAddr, + grpc.WithInsecure(), + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider())))) +``` + +### Baggage +This service makes use of information from Baggage, which originate from an upstream service (frontend). +The `PlaceOrder` function makes use of Baggage to both read, and set Members on it. +Reading userid and requestid from Baggage +```go + // get userID and requestsID from Tracing Baggage + bags := baggage.FromContext(ctx) + userID := bags.Member("userid").Value() + requestID := bags.Member("requestID").Value() +``` + +Setting orderid into Baggage +```go + // Add orderid to Tracing Baggage + orderIDMember, _ := baggage.NewMember("orderid", orderID.String()) + bags, _ = bags.SetMember(orderIDMember) + ctx = baggage.ContextWithBaggage(ctx, bags) +``` diff --git a/src/restservice/demo/msdemo/demo.pb.go b/src/restservice/demo/msdemo/demo.pb.go new file mode 100644 index 0000000..d5eef17 --- /dev/null +++ b/src/restservice/demo/msdemo/demo.pb.go @@ -0,0 +1,2645 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.19.1 +// source: demo.proto + +package msdemo + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CartItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` +} + +func (x *CartItem) Reset() { + *x = CartItem{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CartItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CartItem) ProtoMessage() {} + +func (x *CartItem) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CartItem.ProtoReflect.Descriptor instead. +func (*CartItem) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{0} +} + +func (x *CartItem) GetProductId() string { + if x != nil { + return x.ProductId + } + return "" +} + +func (x *CartItem) GetQuantity() int32 { + if x != nil { + return x.Quantity + } + return 0 +} + +type AddItemRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Item *CartItem `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *AddItemRequest) Reset() { + *x = AddItemRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddItemRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddItemRequest) ProtoMessage() {} + +func (x *AddItemRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddItemRequest.ProtoReflect.Descriptor instead. +func (*AddItemRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{1} +} + +func (x *AddItemRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *AddItemRequest) GetItem() *CartItem { + if x != nil { + return x.Item + } + return nil +} + +type EmptyCartRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` +} + +func (x *EmptyCartRequest) Reset() { + *x = EmptyCartRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmptyCartRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptyCartRequest) ProtoMessage() {} + +func (x *EmptyCartRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmptyCartRequest.ProtoReflect.Descriptor instead. +func (*EmptyCartRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{2} +} + +func (x *EmptyCartRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +type GetCartRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` +} + +func (x *GetCartRequest) Reset() { + *x = GetCartRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetCartRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCartRequest) ProtoMessage() {} + +func (x *GetCartRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCartRequest.ProtoReflect.Descriptor instead. +func (*GetCartRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{3} +} + +func (x *GetCartRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +type Cart struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *Cart) Reset() { + *x = Cart{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Cart) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Cart) ProtoMessage() {} + +func (x *Cart) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Cart.ProtoReflect.Descriptor instead. +func (*Cart) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{4} +} + +func (x *Cart) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *Cart) GetItems() []*CartItem { + if x != nil { + return x.Items + } + return nil +} + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{5} +} + +type ListRecommendationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` +} + +func (x *ListRecommendationsRequest) Reset() { + *x = ListRecommendationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRecommendationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRecommendationsRequest) ProtoMessage() {} + +func (x *ListRecommendationsRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRecommendationsRequest.ProtoReflect.Descriptor instead. +func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{6} +} + +func (x *ListRecommendationsRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *ListRecommendationsRequest) GetProductIds() []string { + if x != nil { + return x.ProductIds + } + return nil +} + +type ListRecommendationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"` +} + +func (x *ListRecommendationsResponse) Reset() { + *x = ListRecommendationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRecommendationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRecommendationsResponse) ProtoMessage() {} + +func (x *ListRecommendationsResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRecommendationsResponse.ProtoReflect.Descriptor instead. +func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{7} +} + +func (x *ListRecommendationsResponse) GetProductIds() []string { + if x != nil { + return x.ProductIds + } + return nil +} + +type Product struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"` + PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"` + // Categories such as "vintage" or "gardening" that can be used to look up + // other related products. + Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` +} + +func (x *Product) Reset() { + *x = Product{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[8] + 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_demo_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product.ProtoReflect.Descriptor instead. +func (*Product) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{8} +} + +func (x *Product) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Product) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Product) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Product) GetPicture() string { + if x != nil { + return x.Picture + } + return "" +} + +func (x *Product) GetPriceUsd() *Money { + if x != nil { + return x.PriceUsd + } + return nil +} + +func (x *Product) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +type ListProductsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"` +} + +func (x *ListProductsResponse) Reset() { + *x = ListProductsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProductsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProductsResponse) ProtoMessage() {} + +func (x *ListProductsResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProductsResponse.ProtoReflect.Descriptor instead. +func (*ListProductsResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{9} +} + +func (x *ListProductsResponse) GetProducts() []*Product { + if x != nil { + return x.Products + } + return nil +} + +type GetProductRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetProductRequest) Reset() { + *x = GetProductRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProductRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProductRequest) ProtoMessage() {} + +func (x *GetProductRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProductRequest.ProtoReflect.Descriptor instead. +func (*GetProductRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{10} +} + +func (x *GetProductRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type SearchProductsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *SearchProductsRequest) Reset() { + *x = SearchProductsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchProductsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchProductsRequest) ProtoMessage() {} + +func (x *SearchProductsRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SearchProductsRequest.ProtoReflect.Descriptor instead. +func (*SearchProductsRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{11} +} + +func (x *SearchProductsRequest) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +type SearchProductsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` +} + +func (x *SearchProductsResponse) Reset() { + *x = SearchProductsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchProductsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchProductsResponse) ProtoMessage() {} + +func (x *SearchProductsResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SearchProductsResponse.ProtoReflect.Descriptor instead. +func (*SearchProductsResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{12} +} + +func (x *SearchProductsResponse) GetResults() []*Product { + if x != nil { + return x.Results + } + return nil +} + +type GetQuoteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *GetQuoteRequest) Reset() { + *x = GetQuoteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetQuoteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetQuoteRequest) ProtoMessage() {} + +func (x *GetQuoteRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetQuoteRequest.ProtoReflect.Descriptor instead. +func (*GetQuoteRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{13} +} + +func (x *GetQuoteRequest) GetAddress() *Address { + if x != nil { + return x.Address + } + return nil +} + +func (x *GetQuoteRequest) GetItems() []*CartItem { + if x != nil { + return x.Items + } + return nil +} + +type GetQuoteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"` +} + +func (x *GetQuoteResponse) Reset() { + *x = GetQuoteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetQuoteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetQuoteResponse) ProtoMessage() {} + +func (x *GetQuoteResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetQuoteResponse.ProtoReflect.Descriptor instead. +func (*GetQuoteResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{14} +} + +func (x *GetQuoteResponse) GetCostUsd() *Money { + if x != nil { + return x.CostUsd + } + return nil +} + +type ShipOrderRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *ShipOrderRequest) Reset() { + *x = ShipOrderRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShipOrderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShipOrderRequest) ProtoMessage() {} + +func (x *ShipOrderRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShipOrderRequest.ProtoReflect.Descriptor instead. +func (*ShipOrderRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{15} +} + +func (x *ShipOrderRequest) GetAddress() *Address { + if x != nil { + return x.Address + } + return nil +} + +func (x *ShipOrderRequest) GetItems() []*CartItem { + if x != nil { + return x.Items + } + return nil +} + +type ShipOrderResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"` +} + +func (x *ShipOrderResponse) Reset() { + *x = ShipOrderResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShipOrderResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShipOrderResponse) ProtoMessage() {} + +func (x *ShipOrderResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShipOrderResponse.ProtoReflect.Descriptor instead. +func (*ShipOrderResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{16} +} + +func (x *ShipOrderResponse) GetTrackingId() string { + if x != nil { + return x.TrackingId + } + return "" +} + +type Address struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"` + City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"` + State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` + Country string `protobuf:"bytes,4,opt,name=country,proto3" json:"country,omitempty"` + ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"` +} + +func (x *Address) Reset() { + *x = Address{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Address) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Address) ProtoMessage() {} + +func (x *Address) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Address.ProtoReflect.Descriptor instead. +func (*Address) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{17} +} + +func (x *Address) GetStreetAddress() string { + if x != nil { + return x.StreetAddress + } + return "" +} + +func (x *Address) GetCity() string { + if x != nil { + return x.City + } + return "" +} + +func (x *Address) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *Address) GetCountry() string { + if x != nil { + return x.Country + } + return "" +} + +func (x *Address) GetZipCode() int32 { + if x != nil { + return x.ZipCode + } + return 0 +} + +// Represents an amount of money with its currency type. +type Money struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The 3-letter currency code defined in ISO 4217. + CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode,proto3" json:"currency_code,omitempty"` + // The whole units of the amount. + // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. + Units int64 `protobuf:"varint,2,opt,name=units,proto3" json:"units,omitempty"` + // Number of nano (10^-9) units of the amount. + // The value must be between -999,999,999 and +999,999,999 inclusive. + // If `units` is positive, `nanos` must be positive or zero. + // If `units` is zero, `nanos` can be positive, zero, or negative. + // If `units` is negative, `nanos` must be negative or zero. + // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. + Nanos int32 `protobuf:"varint,3,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (x *Money) Reset() { + *x = Money{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Money) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Money) ProtoMessage() {} + +func (x *Money) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Money.ProtoReflect.Descriptor instead. +func (*Money) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{18} +} + +func (x *Money) GetCurrencyCode() string { + if x != nil { + return x.CurrencyCode + } + return "" +} + +func (x *Money) GetUnits() int64 { + if x != nil { + return x.Units + } + return 0 +} + +func (x *Money) GetNanos() int32 { + if x != nil { + return x.Nanos + } + return 0 +} + +type GetSupportedCurrenciesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The 3-letter currency code defined in ISO 4217. + CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3" json:"currency_codes,omitempty"` +} + +func (x *GetSupportedCurrenciesResponse) Reset() { + *x = GetSupportedCurrenciesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSupportedCurrenciesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSupportedCurrenciesResponse) ProtoMessage() {} + +func (x *GetSupportedCurrenciesResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSupportedCurrenciesResponse.ProtoReflect.Descriptor instead. +func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{19} +} + +func (x *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string { + if x != nil { + return x.CurrencyCodes + } + return nil +} + +type CurrencyConversionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + From *Money `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + // The 3-letter currency code defined in ISO 4217. + ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode,proto3" json:"to_code,omitempty"` +} + +func (x *CurrencyConversionRequest) Reset() { + *x = CurrencyConversionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CurrencyConversionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CurrencyConversionRequest) ProtoMessage() {} + +func (x *CurrencyConversionRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CurrencyConversionRequest.ProtoReflect.Descriptor instead. +func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{20} +} + +func (x *CurrencyConversionRequest) GetFrom() *Money { + if x != nil { + return x.From + } + return nil +} + +func (x *CurrencyConversionRequest) GetToCode() string { + if x != nil { + return x.ToCode + } + return "" +} + +type CreditCardInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3" json:"credit_card_number,omitempty"` + CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3" json:"credit_card_cvv,omitempty"` + CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3" json:"credit_card_expiration_year,omitempty"` + CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3" json:"credit_card_expiration_month,omitempty"` +} + +func (x *CreditCardInfo) Reset() { + *x = CreditCardInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreditCardInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreditCardInfo) ProtoMessage() {} + +func (x *CreditCardInfo) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreditCardInfo.ProtoReflect.Descriptor instead. +func (*CreditCardInfo) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{21} +} + +func (x *CreditCardInfo) GetCreditCardNumber() string { + if x != nil { + return x.CreditCardNumber + } + return "" +} + +func (x *CreditCardInfo) GetCreditCardCvv() int32 { + if x != nil { + return x.CreditCardCvv + } + return 0 +} + +func (x *CreditCardInfo) GetCreditCardExpirationYear() int32 { + if x != nil { + return x.CreditCardExpirationYear + } + return 0 +} + +func (x *CreditCardInfo) GetCreditCardExpirationMonth() int32 { + if x != nil { + return x.CreditCardExpirationMonth + } + return 0 +} + +type ChargeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Amount *Money `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"` + CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` +} + +func (x *ChargeRequest) Reset() { + *x = ChargeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChargeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChargeRequest) ProtoMessage() {} + +func (x *ChargeRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChargeRequest.ProtoReflect.Descriptor instead. +func (*ChargeRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{22} +} + +func (x *ChargeRequest) GetAmount() *Money { + if x != nil { + return x.Amount + } + return nil +} + +func (x *ChargeRequest) GetCreditCard() *CreditCardInfo { + if x != nil { + return x.CreditCard + } + return nil +} + +type ChargeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` +} + +func (x *ChargeResponse) Reset() { + *x = ChargeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChargeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChargeResponse) ProtoMessage() {} + +func (x *ChargeResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChargeResponse.ProtoReflect.Descriptor instead. +func (*ChargeResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{23} +} + +func (x *ChargeResponse) GetTransactionId() string { + if x != nil { + return x.TransactionId + } + return "" +} + +type OrderItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` + Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"` +} + +func (x *OrderItem) Reset() { + *x = OrderItem{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderItem) ProtoMessage() {} + +func (x *OrderItem) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderItem.ProtoReflect.Descriptor instead. +func (*OrderItem) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{24} +} + +func (x *OrderItem) GetItem() *CartItem { + if x != nil { + return x.Item + } + return nil +} + +func (x *OrderItem) GetCost() *Money { + if x != nil { + return x.Cost + } + return nil +} + +type OrderResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3" json:"shipping_tracking_id,omitempty"` + ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3" json:"shipping_cost,omitempty"` + ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3" json:"shipping_address,omitempty"` + Items []*OrderItem `protobuf:"bytes,5,rep,name=items,proto3" json:"items,omitempty"` +} + +func (x *OrderResult) Reset() { + *x = OrderResult{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderResult) ProtoMessage() {} + +func (x *OrderResult) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderResult.ProtoReflect.Descriptor instead. +func (*OrderResult) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{25} +} + +func (x *OrderResult) GetOrderId() string { + if x != nil { + return x.OrderId + } + return "" +} + +func (x *OrderResult) GetShippingTrackingId() string { + if x != nil { + return x.ShippingTrackingId + } + return "" +} + +func (x *OrderResult) GetShippingCost() *Money { + if x != nil { + return x.ShippingCost + } + return nil +} + +func (x *OrderResult) GetShippingAddress() *Address { + if x != nil { + return x.ShippingAddress + } + return nil +} + +func (x *OrderResult) GetItems() []*OrderItem { + if x != nil { + return x.Items + } + return nil +} + +type SendOrderConfirmationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"` +} + +func (x *SendOrderConfirmationRequest) Reset() { + *x = SendOrderConfirmationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendOrderConfirmationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendOrderConfirmationRequest) ProtoMessage() {} + +func (x *SendOrderConfirmationRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendOrderConfirmationRequest.ProtoReflect.Descriptor instead. +func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{26} +} + +func (x *SendOrderConfirmationRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *SendOrderConfirmationRequest) GetOrder() *OrderResult { + if x != nil { + return x.Order + } + return nil +} + +type PlaceOrderRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency,proto3" json:"user_currency,omitempty"` + Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` + Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"` + CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"` +} + +func (x *PlaceOrderRequest) Reset() { + *x = PlaceOrderRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlaceOrderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlaceOrderRequest) ProtoMessage() {} + +func (x *PlaceOrderRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlaceOrderRequest.ProtoReflect.Descriptor instead. +func (*PlaceOrderRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{27} +} + +func (x *PlaceOrderRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *PlaceOrderRequest) GetUserCurrency() string { + if x != nil { + return x.UserCurrency + } + return "" +} + +func (x *PlaceOrderRequest) GetAddress() *Address { + if x != nil { + return x.Address + } + return nil +} + +func (x *PlaceOrderRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *PlaceOrderRequest) GetCreditCard() *CreditCardInfo { + if x != nil { + return x.CreditCard + } + return nil +} + +type PlaceOrderResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"` +} + +func (x *PlaceOrderResponse) Reset() { + *x = PlaceOrderResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlaceOrderResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlaceOrderResponse) ProtoMessage() {} + +func (x *PlaceOrderResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlaceOrderResponse.ProtoReflect.Descriptor instead. +func (*PlaceOrderResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{28} +} + +func (x *PlaceOrderResponse) GetOrder() *OrderResult { + if x != nil { + return x.Order + } + return nil +} + +type CacheSizeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CacheSize int64 `protobuf:"varint,1,opt,name=cache_size,json=cacheSize,proto3" json:"cache_size,omitempty"` +} + +func (x *CacheSizeResponse) Reset() { + *x = CacheSizeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CacheSizeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CacheSizeResponse) ProtoMessage() {} + +func (x *CacheSizeResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CacheSizeResponse.ProtoReflect.Descriptor instead. +func (*CacheSizeResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{29} +} + +func (x *CacheSizeResponse) GetCacheSize() int64 { + if x != nil { + return x.CacheSize + } + return 0 +} + +type AdRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of important key words from the current page describing the context. + ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys,proto3" json:"context_keys,omitempty"` +} + +func (x *AdRequest) Reset() { + *x = AdRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdRequest) ProtoMessage() {} + +func (x *AdRequest) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdRequest.ProtoReflect.Descriptor instead. +func (*AdRequest) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{30} +} + +func (x *AdRequest) GetContextKeys() []string { + if x != nil { + return x.ContextKeys + } + return nil +} + +type AdResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"` +} + +func (x *AdResponse) Reset() { + *x = AdResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdResponse) ProtoMessage() {} + +func (x *AdResponse) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdResponse.ProtoReflect.Descriptor instead. +func (*AdResponse) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{31} +} + +func (x *AdResponse) GetAds() []*Ad { + if x != nil { + return x.Ads + } + return nil +} + +type Ad struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // url to redirect to when an ad is clicked. + RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"` + // short advertisement text to display. + Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` +} + +func (x *Ad) Reset() { + *x = Ad{} + if protoimpl.UnsafeEnabled { + mi := &file_demo_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Ad) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Ad) ProtoMessage() {} + +func (x *Ad) ProtoReflect() protoreflect.Message { + mi := &file_demo_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Ad.ProtoReflect.Descriptor instead. +func (*Ad) Descriptor() ([]byte, []int) { + return file_demo_proto_rawDescGZIP(), []int{32} +} + +func (x *Ad) GetRedirectUrl() string { + if x != nil { + return x.RedirectUrl + } + return "" +} + +func (x *Ad) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +var File_demo_proto protoreflect.FileDescriptor + +var file_demo_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6d, 0x73, + 0x64, 0x65, 0x6d, 0x6f, 0x22, 0x45, 0x0a, 0x08, 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x4f, 0x0a, 0x0e, 0x41, + 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x61, + 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x2b, 0x0a, 0x10, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x43, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x04, 0x43, 0x61, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x61, + 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x07, 0x0a, + 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, + 0x0b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0x3e, + 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0xb5, + 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2a, 0x0a, 0x09, 0x70, 0x72, + 0x69, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x08, 0x70, 0x72, + 0x69, 0x63, 0x65, 0x55, 0x73, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, + 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x22, 0x23, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x22, 0x2d, 0x0a, 0x15, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, + 0x43, 0x0a, 0x16, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x73, 0x64, + 0x65, 0x6d, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, + 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x26, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, + 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3c, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, + 0x0a, 0x08, 0x63, 0x6f, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, + 0x07, 0x63, 0x6f, 0x73, 0x74, 0x55, 0x73, 0x64, 0x22, 0x65, 0x0a, 0x10, 0x53, 0x68, 0x69, 0x70, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x26, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, + 0x43, 0x61, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, + 0x34, 0x0a, 0x11, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x6b, + 0x69, 0x6e, 0x67, 0x49, 0x64, 0x22, 0x8f, 0x01, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x65, + 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, + 0x7a, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x7a, 0x69, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x58, 0x0a, 0x05, 0x4d, 0x6f, 0x6e, 0x65, 0x79, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, + 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, + 0x73, 0x22, 0x47, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x57, 0x0a, 0x19, 0x43, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4d, + 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x43, + 0x6f, 0x64, 0x65, 0x22, 0xe6, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, + 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, + 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, + 0x61, 0x72, 0x64, 0x5f, 0x63, 0x76, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x43, 0x76, 0x76, 0x12, 0x3d, 0x0a, 0x1b, + 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x18, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x59, 0x65, 0x61, 0x72, 0x12, 0x3f, 0x0a, 0x1c, 0x63, + 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x19, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x45, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x6f, 0x0a, 0x0d, + 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x06, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x5f, 0x63, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x73, 0x64, 0x65, + 0x6d, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x22, 0x37, 0x0a, + 0x0e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x54, 0x0a, 0x09, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, + 0x74, 0x65, 0x6d, 0x12, 0x24, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x61, 0x72, 0x74, 0x49, + 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x21, 0x0a, 0x04, 0x63, 0x6f, 0x73, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, + 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x22, 0xf3, 0x01, 0x0a, + 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x08, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x69, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x54, + 0x72, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x73, 0x68, 0x69, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, + 0x0c, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x3a, 0x0a, + 0x10, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x73, 0x68, 0x69, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, + 0x6f, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x22, 0x5f, 0x0a, 0x1c, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x29, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, + 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x22, 0xcb, 0x01, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, + 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x37, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, + 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, + 0x64, 0x22, 0x3f, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x22, 0x32, 0x0a, 0x11, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x63, 0x68, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x61, 0x63, + 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x2e, 0x0a, 0x09, 0x41, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x2a, 0x0a, 0x0a, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x03, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0a, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x41, 0x64, 0x52, 0x03, 0x61, + 0x64, 0x73, 0x22, 0x3b, 0x0a, 0x02, 0x41, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x32, + 0xac, 0x01, 0x0a, 0x0b, 0x43, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x32, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x2e, 0x6d, 0x73, 0x64, + 0x65, 0x6d, 0x6f, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x12, 0x16, + 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x72, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, + 0x43, 0x61, 0x72, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x43, + 0x61, 0x72, 0x74, 0x12, 0x18, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x43, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, + 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x32, 0x79, + 0x0a, 0x15, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, + 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xe5, 0x01, 0x0a, 0x15, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x73, 0x12, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x12, 0x19, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6d, 0x73, + 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x22, 0x00, 0x12, 0x51, + 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, + 0x12, 0x1d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x32, 0x96, 0x01, 0x0a, 0x0f, 0x53, 0x68, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, + 0x65, 0x12, 0x17, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6d, 0x73, 0x64, + 0x65, 0x6d, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x68, 0x69, + 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x53, 0x68, 0x69, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xa3, 0x01, 0x0a, 0x0f, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, + 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, + 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x3d, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x12, 0x21, 0x2e, 0x6d, + 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x22, 0x00, + 0x32, 0x4b, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x15, 0x2e, 0x6d, + 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x43, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0x5e, 0x0a, + 0x0c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, + 0x15, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, + 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x6d, + 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x32, 0x94, 0x01, + 0x0a, 0x0f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, + 0x19, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x73, 0x64, + 0x65, 0x6d, 0x6f, 0x2e, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x0d, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, + 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, + 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x32, 0x3e, 0x0a, 0x09, 0x41, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x31, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x64, 0x73, 0x12, 0x11, 0x2e, 0x6d, 0x73, + 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, + 0x2e, 0x6d, 0x73, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x0d, 0x5a, 0x0b, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x6d, 0x73, 0x64, + 0x65, 0x6d, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_demo_proto_rawDescOnce sync.Once + file_demo_proto_rawDescData = file_demo_proto_rawDesc +) + +func file_demo_proto_rawDescGZIP() []byte { + file_demo_proto_rawDescOnce.Do(func() { + file_demo_proto_rawDescData = protoimpl.X.CompressGZIP(file_demo_proto_rawDescData) + }) + return file_demo_proto_rawDescData +} + +var file_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 33) +var file_demo_proto_goTypes = []interface{}{ + (*CartItem)(nil), // 0: msdemo.CartItem + (*AddItemRequest)(nil), // 1: msdemo.AddItemRequest + (*EmptyCartRequest)(nil), // 2: msdemo.EmptyCartRequest + (*GetCartRequest)(nil), // 3: msdemo.GetCartRequest + (*Cart)(nil), // 4: msdemo.Cart + (*Empty)(nil), // 5: msdemo.Empty + (*ListRecommendationsRequest)(nil), // 6: msdemo.ListRecommendationsRequest + (*ListRecommendationsResponse)(nil), // 7: msdemo.ListRecommendationsResponse + (*Product)(nil), // 8: msdemo.Product + (*ListProductsResponse)(nil), // 9: msdemo.ListProductsResponse + (*GetProductRequest)(nil), // 10: msdemo.GetProductRequest + (*SearchProductsRequest)(nil), // 11: msdemo.SearchProductsRequest + (*SearchProductsResponse)(nil), // 12: msdemo.SearchProductsResponse + (*GetQuoteRequest)(nil), // 13: msdemo.GetQuoteRequest + (*GetQuoteResponse)(nil), // 14: msdemo.GetQuoteResponse + (*ShipOrderRequest)(nil), // 15: msdemo.ShipOrderRequest + (*ShipOrderResponse)(nil), // 16: msdemo.ShipOrderResponse + (*Address)(nil), // 17: msdemo.Address + (*Money)(nil), // 18: msdemo.Money + (*GetSupportedCurrenciesResponse)(nil), // 19: msdemo.GetSupportedCurrenciesResponse + (*CurrencyConversionRequest)(nil), // 20: msdemo.CurrencyConversionRequest + (*CreditCardInfo)(nil), // 21: msdemo.CreditCardInfo + (*ChargeRequest)(nil), // 22: msdemo.ChargeRequest + (*ChargeResponse)(nil), // 23: msdemo.ChargeResponse + (*OrderItem)(nil), // 24: msdemo.OrderItem + (*OrderResult)(nil), // 25: msdemo.OrderResult + (*SendOrderConfirmationRequest)(nil), // 26: msdemo.SendOrderConfirmationRequest + (*PlaceOrderRequest)(nil), // 27: msdemo.PlaceOrderRequest + (*PlaceOrderResponse)(nil), // 28: msdemo.PlaceOrderResponse + (*CacheSizeResponse)(nil), // 29: msdemo.CacheSizeResponse + (*AdRequest)(nil), // 30: msdemo.AdRequest + (*AdResponse)(nil), // 31: msdemo.AdResponse + (*Ad)(nil), // 32: msdemo.Ad +} +var file_demo_proto_depIdxs = []int32{ + 0, // 0: msdemo.AddItemRequest.item:type_name -> msdemo.CartItem + 0, // 1: msdemo.Cart.items:type_name -> msdemo.CartItem + 18, // 2: msdemo.Product.price_usd:type_name -> msdemo.Money + 8, // 3: msdemo.ListProductsResponse.products:type_name -> msdemo.Product + 8, // 4: msdemo.SearchProductsResponse.results:type_name -> msdemo.Product + 17, // 5: msdemo.GetQuoteRequest.address:type_name -> msdemo.Address + 0, // 6: msdemo.GetQuoteRequest.items:type_name -> msdemo.CartItem + 18, // 7: msdemo.GetQuoteResponse.cost_usd:type_name -> msdemo.Money + 17, // 8: msdemo.ShipOrderRequest.address:type_name -> msdemo.Address + 0, // 9: msdemo.ShipOrderRequest.items:type_name -> msdemo.CartItem + 18, // 10: msdemo.CurrencyConversionRequest.from:type_name -> msdemo.Money + 18, // 11: msdemo.ChargeRequest.amount:type_name -> msdemo.Money + 21, // 12: msdemo.ChargeRequest.credit_card:type_name -> msdemo.CreditCardInfo + 0, // 13: msdemo.OrderItem.item:type_name -> msdemo.CartItem + 18, // 14: msdemo.OrderItem.cost:type_name -> msdemo.Money + 18, // 15: msdemo.OrderResult.shipping_cost:type_name -> msdemo.Money + 17, // 16: msdemo.OrderResult.shipping_address:type_name -> msdemo.Address + 24, // 17: msdemo.OrderResult.items:type_name -> msdemo.OrderItem + 25, // 18: msdemo.SendOrderConfirmationRequest.order:type_name -> msdemo.OrderResult + 17, // 19: msdemo.PlaceOrderRequest.address:type_name -> msdemo.Address + 21, // 20: msdemo.PlaceOrderRequest.credit_card:type_name -> msdemo.CreditCardInfo + 25, // 21: msdemo.PlaceOrderResponse.order:type_name -> msdemo.OrderResult + 32, // 22: msdemo.AdResponse.ads:type_name -> msdemo.Ad + 1, // 23: msdemo.CartService.AddItem:input_type -> msdemo.AddItemRequest + 3, // 24: msdemo.CartService.GetCart:input_type -> msdemo.GetCartRequest + 2, // 25: msdemo.CartService.EmptyCart:input_type -> msdemo.EmptyCartRequest + 6, // 26: msdemo.RecommendationService.ListRecommendations:input_type -> msdemo.ListRecommendationsRequest + 5, // 27: msdemo.ProductCatalogService.ListProducts:input_type -> msdemo.Empty + 10, // 28: msdemo.ProductCatalogService.GetProduct:input_type -> msdemo.GetProductRequest + 11, // 29: msdemo.ProductCatalogService.SearchProducts:input_type -> msdemo.SearchProductsRequest + 13, // 30: msdemo.ShippingService.GetQuote:input_type -> msdemo.GetQuoteRequest + 15, // 31: msdemo.ShippingService.ShipOrder:input_type -> msdemo.ShipOrderRequest + 5, // 32: msdemo.CurrencyService.GetSupportedCurrencies:input_type -> msdemo.Empty + 20, // 33: msdemo.CurrencyService.Convert:input_type -> msdemo.CurrencyConversionRequest + 22, // 34: msdemo.PaymentService.Charge:input_type -> msdemo.ChargeRequest + 26, // 35: msdemo.EmailService.SendOrderConfirmation:input_type -> msdemo.SendOrderConfirmationRequest + 27, // 36: msdemo.CheckoutService.PlaceOrder:input_type -> msdemo.PlaceOrderRequest + 5, // 37: msdemo.CheckoutService.GetCacheSize:input_type -> msdemo.Empty + 30, // 38: msdemo.AdService.GetAds:input_type -> msdemo.AdRequest + 5, // 39: msdemo.CartService.AddItem:output_type -> msdemo.Empty + 4, // 40: msdemo.CartService.GetCart:output_type -> msdemo.Cart + 5, // 41: msdemo.CartService.EmptyCart:output_type -> msdemo.Empty + 7, // 42: msdemo.RecommendationService.ListRecommendations:output_type -> msdemo.ListRecommendationsResponse + 9, // 43: msdemo.ProductCatalogService.ListProducts:output_type -> msdemo.ListProductsResponse + 8, // 44: msdemo.ProductCatalogService.GetProduct:output_type -> msdemo.Product + 12, // 45: msdemo.ProductCatalogService.SearchProducts:output_type -> msdemo.SearchProductsResponse + 14, // 46: msdemo.ShippingService.GetQuote:output_type -> msdemo.GetQuoteResponse + 16, // 47: msdemo.ShippingService.ShipOrder:output_type -> msdemo.ShipOrderResponse + 19, // 48: msdemo.CurrencyService.GetSupportedCurrencies:output_type -> msdemo.GetSupportedCurrenciesResponse + 18, // 49: msdemo.CurrencyService.Convert:output_type -> msdemo.Money + 23, // 50: msdemo.PaymentService.Charge:output_type -> msdemo.ChargeResponse + 5, // 51: msdemo.EmailService.SendOrderConfirmation:output_type -> msdemo.Empty + 28, // 52: msdemo.CheckoutService.PlaceOrder:output_type -> msdemo.PlaceOrderResponse + 29, // 53: msdemo.CheckoutService.GetCacheSize:output_type -> msdemo.CacheSizeResponse + 31, // 54: msdemo.AdService.GetAds:output_type -> msdemo.AdResponse + 39, // [39:55] is the sub-list for method output_type + 23, // [23:39] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name +} + +func init() { file_demo_proto_init() } +func file_demo_proto_init() { + if File_demo_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_demo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CartItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddItemRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmptyCartRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetCartRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Cart); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRecommendationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRecommendationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Product); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProductsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProductRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchProductsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchProductsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetQuoteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetQuoteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShipOrderRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShipOrderResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Address); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Money); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSupportedCurrenciesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CurrencyConversionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreditCardInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChargeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChargeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendOrderConfirmationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlaceOrderRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlaceOrderResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CacheSizeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_demo_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Ad); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_demo_proto_rawDesc, + NumEnums: 0, + NumMessages: 33, + NumExtensions: 0, + NumServices: 9, + }, + GoTypes: file_demo_proto_goTypes, + DependencyIndexes: file_demo_proto_depIdxs, + MessageInfos: file_demo_proto_msgTypes, + }.Build() + File_demo_proto = out.File + file_demo_proto_rawDesc = nil + file_demo_proto_goTypes = nil + file_demo_proto_depIdxs = nil +} \ No newline at end of file diff --git a/src/restservice/demo/msdemo/demo_grpc.pb.go b/src/restservice/demo/msdemo/demo_grpc.pb.go new file mode 100644 index 0000000..a7f4bc7 --- /dev/null +++ b/src/restservice/demo/msdemo/demo_grpc.pb.go @@ -0,0 +1,1027 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.19.1 +// source: demo.proto + +package msdemo + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// CartServiceClient is the client API for CartService 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 CartServiceClient interface { + AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) + GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) + EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) +} + +type cartServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCartServiceClient(cc grpc.ClientConnInterface) CartServiceClient { + return &cartServiceClient{cc} +} + +func (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/msdemo.CartService/AddItem", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) { + out := new(Cart) + err := c.cc.Invoke(ctx, "/msdemo.CartService/GetCart", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/msdemo.CartService/EmptyCart", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CartServiceServer is the server API for CartService service. +// All implementations should embed UnimplementedCartServiceServer +// for forward compatibility +type CartServiceServer interface { + AddItem(context.Context, *AddItemRequest) (*Empty, error) + GetCart(context.Context, *GetCartRequest) (*Cart, error) + EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) +} + +// UnimplementedCartServiceServer should be embedded to have forward compatible implementations. +type UnimplementedCartServiceServer struct { +} + +func (UnimplementedCartServiceServer) AddItem(context.Context, *AddItemRequest) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddItem not implemented") +} +func (UnimplementedCartServiceServer) GetCart(context.Context, *GetCartRequest) (*Cart, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCart not implemented") +} +func (UnimplementedCartServiceServer) EmptyCart(context.Context, *EmptyCartRequest) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method EmptyCart not implemented") +} + +// UnsafeCartServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CartServiceServer will +// result in compilation errors. +type UnsafeCartServiceServer interface { + mustEmbedUnimplementedCartServiceServer() +} + +func RegisterCartServiceServer(s grpc.ServiceRegistrar, srv CartServiceServer) { + s.RegisterService(&CartService_ServiceDesc, srv) +} + +func _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddItemRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CartServiceServer).AddItem(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CartService/AddItem", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetCartRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CartServiceServer).GetCart(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CartService/GetCart", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EmptyCartRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CartServiceServer).EmptyCart(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CartService/EmptyCart", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CartService_ServiceDesc is the grpc.ServiceDesc for CartService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CartService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.CartService", + HandlerType: (*CartServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AddItem", + Handler: _CartService_AddItem_Handler, + }, + { + MethodName: "GetCart", + Handler: _CartService_GetCart_Handler, + }, + { + MethodName: "EmptyCart", + Handler: _CartService_EmptyCart_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// RecommendationServiceClient is the client API for RecommendationService 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 RecommendationServiceClient interface { + ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) +} + +type recommendationServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRecommendationServiceClient(cc grpc.ClientConnInterface) RecommendationServiceClient { + return &recommendationServiceClient{cc} +} + +func (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) { + out := new(ListRecommendationsResponse) + err := c.cc.Invoke(ctx, "/msdemo.RecommendationService/ListRecommendations", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RecommendationServiceServer is the server API for RecommendationService service. +// All implementations should embed UnimplementedRecommendationServiceServer +// for forward compatibility +type RecommendationServiceServer interface { + ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) +} + +// UnimplementedRecommendationServiceServer should be embedded to have forward compatible implementations. +type UnimplementedRecommendationServiceServer struct { +} + +func (UnimplementedRecommendationServiceServer) ListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListRecommendations not implemented") +} + +// UnsafeRecommendationServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to RecommendationServiceServer will +// result in compilation errors. +type UnsafeRecommendationServiceServer interface { + mustEmbedUnimplementedRecommendationServiceServer() +} + +func RegisterRecommendationServiceServer(s grpc.ServiceRegistrar, srv RecommendationServiceServer) { + s.RegisterService(&RecommendationService_ServiceDesc, srv) +} + +func _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRecommendationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecommendationServiceServer).ListRecommendations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.RecommendationService/ListRecommendations", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// RecommendationService_ServiceDesc is the grpc.ServiceDesc for RecommendationService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var RecommendationService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.RecommendationService", + HandlerType: (*RecommendationServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListRecommendations", + Handler: _RecommendationService_ListRecommendations_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// ProductCatalogServiceClient is the client API for ProductCatalogService 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 ProductCatalogServiceClient interface { + ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) + GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) + SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) +} + +type productCatalogServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProductCatalogServiceClient(cc grpc.ClientConnInterface) ProductCatalogServiceClient { + return &productCatalogServiceClient{cc} +} + +func (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) { + out := new(ListProductsResponse) + err := c.cc.Invoke(ctx, "/msdemo.ProductCatalogService/ListProducts", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) { + out := new(Product) + err := c.cc.Invoke(ctx, "/msdemo.ProductCatalogService/GetProduct", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) { + out := new(SearchProductsResponse) + err := c.cc.Invoke(ctx, "/msdemo.ProductCatalogService/SearchProducts", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ProductCatalogServiceServer is the server API for ProductCatalogService service. +// All implementations should embed UnimplementedProductCatalogServiceServer +// for forward compatibility +type ProductCatalogServiceServer interface { + ListProducts(context.Context, *Empty) (*ListProductsResponse, error) + GetProduct(context.Context, *GetProductRequest) (*Product, error) + SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) +} + +// UnimplementedProductCatalogServiceServer should be embedded to have forward compatible implementations. +type UnimplementedProductCatalogServiceServer struct { +} + +func (UnimplementedProductCatalogServiceServer) ListProducts(context.Context, *Empty) (*ListProductsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListProducts not implemented") +} +func (UnimplementedProductCatalogServiceServer) GetProduct(context.Context, *GetProductRequest) (*Product, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetProduct not implemented") +} +func (UnimplementedProductCatalogServiceServer) SearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SearchProducts not implemented") +} + +// UnsafeProductCatalogServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProductCatalogServiceServer will +// result in compilation errors. +type UnsafeProductCatalogServiceServer interface { + mustEmbedUnimplementedProductCatalogServiceServer() +} + +func RegisterProductCatalogServiceServer(s grpc.ServiceRegistrar, srv ProductCatalogServiceServer) { + s.RegisterService(&ProductCatalogService_ServiceDesc, srv) +} + +func _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductCatalogServiceServer).ListProducts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.ProductCatalogService/ListProducts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductCatalogService_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetProductRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductCatalogServiceServer).GetProduct(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.ProductCatalogService/GetProduct", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SearchProductsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductCatalogServiceServer).SearchProducts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.ProductCatalogService/SearchProducts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ProductCatalogService_ServiceDesc is the grpc.ServiceDesc for ProductCatalogService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProductCatalogService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.ProductCatalogService", + HandlerType: (*ProductCatalogServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListProducts", + Handler: _ProductCatalogService_ListProducts_Handler, + }, + { + MethodName: "GetProduct", + Handler: _ProductCatalogService_GetProduct_Handler, + }, + { + MethodName: "SearchProducts", + Handler: _ProductCatalogService_SearchProducts_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// ShippingServiceClient is the client API for ShippingService 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 ShippingServiceClient interface { + GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) + ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) +} + +type shippingServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewShippingServiceClient(cc grpc.ClientConnInterface) ShippingServiceClient { + return &shippingServiceClient{cc} +} + +func (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) { + out := new(GetQuoteResponse) + err := c.cc.Invoke(ctx, "/msdemo.ShippingService/GetQuote", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) { + out := new(ShipOrderResponse) + err := c.cc.Invoke(ctx, "/msdemo.ShippingService/ShipOrder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ShippingServiceServer is the server API for ShippingService service. +// All implementations should embed UnimplementedShippingServiceServer +// for forward compatibility +type ShippingServiceServer interface { + GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) + ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) +} + +// UnimplementedShippingServiceServer should be embedded to have forward compatible implementations. +type UnimplementedShippingServiceServer struct { +} + +func (UnimplementedShippingServiceServer) GetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetQuote not implemented") +} +func (UnimplementedShippingServiceServer) ShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShipOrder not implemented") +} + +// UnsafeShippingServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ShippingServiceServer will +// result in compilation errors. +type UnsafeShippingServiceServer interface { + mustEmbedUnimplementedShippingServiceServer() +} + +func RegisterShippingServiceServer(s grpc.ServiceRegistrar, srv ShippingServiceServer) { + s.RegisterService(&ShippingService_ServiceDesc, srv) +} + +func _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetQuoteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ShippingServiceServer).GetQuote(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.ShippingService/GetQuote", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ShipOrderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ShippingServiceServer).ShipOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.ShippingService/ShipOrder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ShippingService_ServiceDesc is the grpc.ServiceDesc for ShippingService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ShippingService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.ShippingService", + HandlerType: (*ShippingServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetQuote", + Handler: _ShippingService_GetQuote_Handler, + }, + { + MethodName: "ShipOrder", + Handler: _ShippingService_ShipOrder_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// CurrencyServiceClient is the client API for CurrencyService 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 CurrencyServiceClient interface { + GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) + Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) +} + +type currencyServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCurrencyServiceClient(cc grpc.ClientConnInterface) CurrencyServiceClient { + return ¤cyServiceClient{cc} +} + +func (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) { + out := new(GetSupportedCurrenciesResponse) + err := c.cc.Invoke(ctx, "/msdemo.CurrencyService/GetSupportedCurrencies", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) { + out := new(Money) + err := c.cc.Invoke(ctx, "/msdemo.CurrencyService/Convert", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CurrencyServiceServer is the server API for CurrencyService service. +// All implementations should embed UnimplementedCurrencyServiceServer +// for forward compatibility +type CurrencyServiceServer interface { + GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) + Convert(context.Context, *CurrencyConversionRequest) (*Money, error) +} + +// UnimplementedCurrencyServiceServer should be embedded to have forward compatible implementations. +type UnimplementedCurrencyServiceServer struct { +} + +func (UnimplementedCurrencyServiceServer) GetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSupportedCurrencies not implemented") +} +func (UnimplementedCurrencyServiceServer) Convert(context.Context, *CurrencyConversionRequest) (*Money, error) { + return nil, status.Errorf(codes.Unimplemented, "method Convert not implemented") +} + +// UnsafeCurrencyServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CurrencyServiceServer will +// result in compilation errors. +type UnsafeCurrencyServiceServer interface { + mustEmbedUnimplementedCurrencyServiceServer() +} + +func RegisterCurrencyServiceServer(s grpc.ServiceRegistrar, srv CurrencyServiceServer) { + s.RegisterService(&CurrencyService_ServiceDesc, srv) +} + +func _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CurrencyService/GetSupportedCurrencies", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CurrencyConversionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CurrencyServiceServer).Convert(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CurrencyService/Convert", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CurrencyService_ServiceDesc is the grpc.ServiceDesc for CurrencyService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CurrencyService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.CurrencyService", + HandlerType: (*CurrencyServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetSupportedCurrencies", + Handler: _CurrencyService_GetSupportedCurrencies_Handler, + }, + { + MethodName: "Convert", + Handler: _CurrencyService_Convert_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// PaymentServiceClient is the client API for PaymentService 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 PaymentServiceClient interface { + Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) +} + +type paymentServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPaymentServiceClient(cc grpc.ClientConnInterface) PaymentServiceClient { + return &paymentServiceClient{cc} +} + +func (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) { + out := new(ChargeResponse) + err := c.cc.Invoke(ctx, "/msdemo.PaymentService/Charge", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PaymentServiceServer is the server API for PaymentService service. +// All implementations should embed UnimplementedPaymentServiceServer +// for forward compatibility +type PaymentServiceServer interface { + Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) +} + +// UnimplementedPaymentServiceServer should be embedded to have forward compatible implementations. +type UnimplementedPaymentServiceServer struct { +} + +func (UnimplementedPaymentServiceServer) Charge(context.Context, *ChargeRequest) (*ChargeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Charge not implemented") +} + +// UnsafePaymentServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PaymentServiceServer will +// result in compilation errors. +type UnsafePaymentServiceServer interface { + mustEmbedUnimplementedPaymentServiceServer() +} + +func RegisterPaymentServiceServer(s grpc.ServiceRegistrar, srv PaymentServiceServer) { + s.RegisterService(&PaymentService_ServiceDesc, srv) +} + +func _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChargeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PaymentServiceServer).Charge(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.PaymentService/Charge", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// PaymentService_ServiceDesc is the grpc.ServiceDesc for PaymentService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PaymentService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.PaymentService", + HandlerType: (*PaymentServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Charge", + Handler: _PaymentService_Charge_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// EmailServiceClient is the client API for EmailService 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 EmailServiceClient interface { + SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) +} + +type emailServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewEmailServiceClient(cc grpc.ClientConnInterface) EmailServiceClient { + return &emailServiceClient{cc} +} + +func (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/msdemo.EmailService/SendOrderConfirmation", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// EmailServiceServer is the server API for EmailService service. +// All implementations should embed UnimplementedEmailServiceServer +// for forward compatibility +type EmailServiceServer interface { + SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) +} + +// UnimplementedEmailServiceServer should be embedded to have forward compatible implementations. +type UnimplementedEmailServiceServer struct { +} + +func (UnimplementedEmailServiceServer) SendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendOrderConfirmation not implemented") +} + +// UnsafeEmailServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to EmailServiceServer will +// result in compilation errors. +type UnsafeEmailServiceServer interface { + mustEmbedUnimplementedEmailServiceServer() +} + +func RegisterEmailServiceServer(s grpc.ServiceRegistrar, srv EmailServiceServer) { + s.RegisterService(&EmailService_ServiceDesc, srv) +} + +func _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendOrderConfirmationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EmailServiceServer).SendOrderConfirmation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.EmailService/SendOrderConfirmation", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// EmailService_ServiceDesc is the grpc.ServiceDesc for EmailService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var EmailService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.EmailService", + HandlerType: (*EmailServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SendOrderConfirmation", + Handler: _EmailService_SendOrderConfirmation_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// CheckoutServiceClient is the client API for CheckoutService 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 CheckoutServiceClient interface { + PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) + GetCacheSize(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*CacheSizeResponse, error) +} + +type checkoutServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCheckoutServiceClient(cc grpc.ClientConnInterface) CheckoutServiceClient { + return &checkoutServiceClient{cc} +} + +func (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) { + out := new(PlaceOrderResponse) + err := c.cc.Invoke(ctx, "/msdemo.CheckoutService/PlaceOrder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *checkoutServiceClient) GetCacheSize(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*CacheSizeResponse, error) { + out := new(CacheSizeResponse) + err := c.cc.Invoke(ctx, "/msdemo.CheckoutService/GetCacheSize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CheckoutServiceServer is the server API for CheckoutService service. +// All implementations should embed UnimplementedCheckoutServiceServer +// for forward compatibility +type CheckoutServiceServer interface { + PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) + GetCacheSize(context.Context, *Empty) (*CacheSizeResponse, error) +} + +// UnimplementedCheckoutServiceServer should be embedded to have forward compatible implementations. +type UnimplementedCheckoutServiceServer struct { +} + +func (UnimplementedCheckoutServiceServer) PlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PlaceOrder not implemented") +} +func (UnimplementedCheckoutServiceServer) GetCacheSize(context.Context, *Empty) (*CacheSizeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCacheSize not implemented") +} + +// UnsafeCheckoutServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CheckoutServiceServer will +// result in compilation errors. +type UnsafeCheckoutServiceServer interface { + mustEmbedUnimplementedCheckoutServiceServer() +} + +func RegisterCheckoutServiceServer(s grpc.ServiceRegistrar, srv CheckoutServiceServer) { + s.RegisterService(&CheckoutService_ServiceDesc, srv) +} + +func _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PlaceOrderRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CheckoutServiceServer).PlaceOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CheckoutService/PlaceOrder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CheckoutService_GetCacheSize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CheckoutServiceServer).GetCacheSize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.CheckoutService/GetCacheSize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CheckoutServiceServer).GetCacheSize(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +// CheckoutService_ServiceDesc is the grpc.ServiceDesc for CheckoutService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CheckoutService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.CheckoutService", + HandlerType: (*CheckoutServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PlaceOrder", + Handler: _CheckoutService_PlaceOrder_Handler, + }, + { + MethodName: "GetCacheSize", + Handler: _CheckoutService_GetCacheSize_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} + +// AdServiceClient is the client API for AdService 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 AdServiceClient interface { + GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) +} + +type adServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAdServiceClient(cc grpc.ClientConnInterface) AdServiceClient { + return &adServiceClient{cc} +} + +func (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) { + out := new(AdResponse) + err := c.cc.Invoke(ctx, "/msdemo.AdService/GetAds", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AdServiceServer is the server API for AdService service. +// All implementations should embed UnimplementedAdServiceServer +// for forward compatibility +type AdServiceServer interface { + GetAds(context.Context, *AdRequest) (*AdResponse, error) +} + +// UnimplementedAdServiceServer should be embedded to have forward compatible implementations. +type UnimplementedAdServiceServer struct { +} + +func (UnimplementedAdServiceServer) GetAds(context.Context, *AdRequest) (*AdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAds not implemented") +} + +// UnsafeAdServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AdServiceServer will +// result in compilation errors. +type UnsafeAdServiceServer interface { + mustEmbedUnimplementedAdServiceServer() +} + +func RegisterAdServiceServer(s grpc.ServiceRegistrar, srv AdServiceServer) { + s.RegisterService(&AdService_ServiceDesc, srv) +} + +func _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdServiceServer).GetAds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/msdemo.AdService/GetAds", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AdService_ServiceDesc is the grpc.ServiceDesc for AdService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AdService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "msdemo.AdService", + HandlerType: (*AdServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAds", + Handler: _AdService_GetAds_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "demo.proto", +} \ No newline at end of file diff --git a/src/restservice/genproto.sh b/src/restservice/genproto.sh new file mode 100755 index 0000000..69cf793 --- /dev/null +++ b/src/restservice/genproto.sh @@ -0,0 +1,7 @@ +#!/bin/bash -eu + +PATH=$PATH:$GOPATH/bin +protodir=../../pb + +protoc --go_out=. --go-grpc_out=require_unimplemented_servers=false:. --proto_path=$protodir $protodir/demo.proto + diff --git a/src/restservice/go.mod b/src/restservice/go.mod new file mode 100644 index 0000000..80c5557 --- /dev/null +++ b/src/restservice/go.mod @@ -0,0 +1,31 @@ +module github.com/honeycombio/microservices-demo/src/checkoutservice + +go 1.17 + +require ( + github.com/google/uuid v1.1.2 + github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/sirupsen/logrus v1.8.1 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 + go.opentelemetry.io/otel v1.4.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0 + go.opentelemetry.io/otel/sdk v1.4.0 + go.opentelemetry.io/otel/trace v1.4.0 + google.golang.org/grpc v1.44.0 + google.golang.org/protobuf v1.27.1 +) + +require ( + github.com/cenkalti/backoff/v4 v4.1.2 // indirect + github.com/go-logr/logr v1.2.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0 // indirect + go.opentelemetry.io/proto/otlp v0.12.0 // indirect + golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 // indirect + golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect + golang.org/x/text v0.3.6 // indirect + google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 // indirect +) diff --git a/src/restservice/go.sum b/src/restservice/go.sum new file mode 100644 index 0000000..0e0d4e9 --- /dev/null +++ b/src/restservice/go.sum @@ -0,0 +1,197 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +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/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 h1:n9b7AAdbQtQ0k9dm0Dm2/KUcUqtG8i2O15KzNaDze8c= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0/go.mod h1:LsankqVDx4W+RhZNA5uWarULII/MBhF5qwCYxTuyXjs= +go.opentelemetry.io/otel v1.4.0 h1:7ESuKPq6zpjRaY5nvVDGiuwK7VAJ8MwkKnmNJ9whNZ4= +go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0 h1:j7AwzDdAQBJjcqayAaYbvpYeZzII7cEe5qJTu+De6UY= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0 h1:lRpP10E8oTGVmY1nVXcwelCT1Z8ca41/l5ce7AqLAss= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0/go.mod h1:3oS+j2WUoJVyj6/BzQN/52G17lNJDulngsOxDm1w2PY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0 h1:buSx4AMC/0Z232slPhicN/fU5KIlj0bMngct5pcZhkI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0/go.mod h1:ew1NcwkHo0QFT3uTm3m2IVZMkZdVIpbOYNPasgWwpdk= +go.opentelemetry.io/otel/sdk v1.4.0 h1:LJE4SW3jd4lQTESnlpQZcBhQ3oci0U2MLR5uhicfTHQ= +go.opentelemetry.io/otel/sdk v1.4.0/go.mod h1:71GJPNJh4Qju6zJuYl1CrYtXbrgfau/M9UAggqiy1UE= +go.opentelemetry.io/otel/trace v1.4.0 h1:4OOUrPZdVFQkbzl/JSdvGCWIdw5ONXXxzHlaLlWppmo= +go.opentelemetry.io/otel/trace v1.4.0/go.mod h1:uc3eRsqDfWs9R7b92xbQbU42/eTNz4N+gLP8qJCi4aE= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= +go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/src/restservice/main.go b/src/restservice/main.go new file mode 100644 index 0000000..e23e488 --- /dev/null +++ b/src/restservice/main.go @@ -0,0 +1,150 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + + pb "github.com/honeycombio/microservices-demo/src/checkoutservice/demo/msdemo" + "github.com/sirupsen/logrus" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "google.golang.org/grpc" +) + +type Message struct { + FromAmount float64 `json:"fromAmount"` + FromCurrency string `json:"fromCurrency"` + ToCurrency string `json:"toCurrency"` +} + +func initOtelTracing(ctx context.Context, log logrus.FieldLogger) *sdktrace.TracerProvider { + endpoint := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") + if endpoint == "" { + endpoint = "opentelemetry-collector:4317" + } + + // Set GRPC options to establish an insecure connection to an OpenTelemetry Collector + // To establish a TLS connection to a secured endpoint use: + // otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")) + opts := []otlptracegrpc.Option{ + otlptracegrpc.WithEndpoint(endpoint), + otlptracegrpc.WithInsecure(), + } + + // Create the exporter + exporter, err := otlptrace.New(ctx, otlptracegrpc.NewClient(opts...)) + if err != nil { + log.Fatal(err) + } + + // Specify the TextMapPropagator to ensure spans propagate across service boundaries + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})) + + // Set standard attributes per semantic conventions + res := resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String("checkout"), + ) + + // Create and set the TraceProvider + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(res), + ) + otel.SetTracerProvider(tp) + + return tp +} + +func messageHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + return + } + + body, err := ioutil.ReadAll(r.Body) + if err != nil { + http.Error(w, "Error reading request body", http.StatusInternalServerError) + return + } + defer r.Body.Close() + + var msg Message + err = json.Unmarshal(body, &msg) + if err != nil { + http.Error(w, "Error unmarshalling JSON", http.StatusBadRequest) + return + } + + // Create a restService instance and call the convertCurrency function + cs := &restService{currencySvcAddr: "currencyservice:7000"} + from := &pb.Money{CurrencyCode: msg.FromCurrency, Units: int64(msg.FromAmount), Nanos: int32(msg.FromAmount*1e9) % 1e9} + converted, err := cs.convertCurrency(context.Background(), from, msg.ToCurrency) + if err != nil { + http.Error(w, "Error converting currency", http.StatusInternalServerError) + return + } + + // Prepare the response JSON + response := map[string]interface{}{ + "fromAmount": msg.FromAmount, + "fromCurrency": msg.FromCurrency, + "toAmount": float64(converted.Units) + float64(converted.Nanos)/1e9, + "toCurrency": msg.ToCurrency, + } + + responseJSON, err := json.Marshal(response) + if err != nil { + http.Error(w, "Error marshalling JSON", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(responseJSON) +} + +func main() { + http.HandleFunc("/", messageHandler) + log.Fatal(http.ListenAndServe(":5051", nil)) + + //call the convertCurrency function + +} + +type restService struct { + currencySvcAddr string +} + +func (cs *restService) convertCurrency(ctx context.Context, from *pb.Money, toCurrency string) (*pb.Money, error) { + // add OpenTelemetry instrumentation to outgoing gRPC requests + conn, err := grpc.DialContext(ctx, cs.currencySvcAddr, grpc.WithInsecure(), + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider())))) + + if err != nil { + return nil, fmt.Errorf("could not connect currency service: %+v", err) + } + defer func(conn *grpc.ClientConn) { + _ = conn.Close() + }(conn) + result, err := pb.NewCurrencyServiceClient(conn).Convert(ctx, &pb.CurrencyConversionRequest{ + From: from, + ToCode: toCurrency}) + if err != nil { + return nil, fmt.Errorf("failed to convert currency: %+v", err) + } + //sleepRandom(20) + return result, err +} diff --git a/src/restservice/money/money.go b/src/restservice/money/money.go new file mode 100644 index 0000000..1d76eb8 --- /dev/null +++ b/src/restservice/money/money.go @@ -0,0 +1,117 @@ +package money + +import ( + "errors" + + pb "github.com/honeycombio/microservices-demo/src/checkoutservice/demo/msdemo" +) + +const ( + nanosMin = -999999999 + nanosMax = +999999999 + nanosMod = 1000000000 +) + +var ( + ErrInvalidValue = errors.New("one of the specified money values is invalid") + ErrMismatchingCurrency = errors.New("mismatching currency codes") +) + +// IsValid checks if specified value has a valid units/nanos signs and ranges. +func IsValid(m pb.Money) bool { + return signMatches(m) && validNanos(m.GetNanos()) +} + +func signMatches(m pb.Money) bool { + return m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0) +} + +func validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax } + +// IsZero returns true if the specified money value is equal to zero. +func IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 } + +// IsPositive returns true if the specified money value is valid and is +// positive. +func IsPositive(m pb.Money) bool { + return IsValid(m) && m.GetUnits() > 0 || (m.GetUnits() == 0 && m.GetNanos() > 0) +} + +// IsNegative returns true if the specified money value is valid and is +// negative. +func IsNegative(m pb.Money) bool { + return IsValid(m) && m.GetUnits() < 0 || (m.GetUnits() == 0 && m.GetNanos() < 0) +} + +// AreSameCurrency returns true if values l and r have a currency code, and they are the same values. +func AreSameCurrency(l, r pb.Money) bool { + return l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetCurrencyCode() != "" +} + +// AreEquals returns true if values l and r are the equal, including the +// currency. This does not check validity of the provided values. +func AreEquals(l, r pb.Money) bool { + return l.GetCurrencyCode() == r.GetCurrencyCode() && + l.GetUnits() == r.GetUnits() && l.GetNanos() == r.GetNanos() +} + +// Negate returns the same amount with the sign negated. +func Negate(m pb.Money) pb.Money { + return pb.Money{ + Units: -m.GetUnits(), + Nanos: -m.GetNanos(), + CurrencyCode: m.GetCurrencyCode()} +} + +// Must panics if the given error is not nil. This can be used with other +// functions like: "m := Must(Sum(a,b))". +func Must(v pb.Money, err error) pb.Money { + if err != nil { + panic(err) + } + return v +} + +// Sum adds two values. Returns an error if one of the values are invalid or +// currency codes are not matching (unless currency code is unspecified for +// both). +func Sum(l, r pb.Money) (pb.Money, error) { + if !IsValid(l) || !IsValid(r) { + return pb.Money{}, ErrInvalidValue + } else if l.GetCurrencyCode() != r.GetCurrencyCode() { + return pb.Money{}, ErrMismatchingCurrency + } + units := l.GetUnits() + r.GetUnits() + nanos := l.GetNanos() + r.GetNanos() + + if (units == 0 && nanos == 0) || (units > 0 && nanos >= 0) || (units < 0 && nanos <= 0) { + // same sign + units += int64(nanos / nanosMod) + nanos = nanos % nanosMod + } else { + // different sign. nanos guaranteed to not go over the limit + if units > 0 { + units-- + nanos += nanosMod + } else { + units++ + nanos -= nanosMod + } + } + + return pb.Money{ + Units: units, + Nanos: nanos, + CurrencyCode: l.GetCurrencyCode()}, nil +} + +// MultiplySlow is a slow multiplication operation done through adding the value +// to itself n-1 times. +func MultiplySlow(m pb.Money, n uint32) pb.Money { + out := m + for n > 1 { + out = Must(Sum(out, m)) + n-- + } + return out +} diff --git a/src/restservice/money/money_test.go b/src/restservice/money/money_test.go new file mode 100644 index 0000000..daa7e82 --- /dev/null +++ b/src/restservice/money/money_test.go @@ -0,0 +1,231 @@ +package money + +import ( + "fmt" + "reflect" + "testing" + + pb "github.com/honeycombio/microservices-demo/src/checkoutservice/demo/msdemo" +) + +func mmc(u int64, n int32, c string) pb.Money { return pb.Money{Units: u, Nanos: n, CurrencyCode: c} } +func mm(u int64, n int32) pb.Money { return mmc(u, n, "") } + +func TestIsValid(t *testing.T) { + tests := []struct { + name string + in pb.Money + want bool + }{ + {"valid -/-", mm(-981273891273, -999999999), true}, + {"invalid -/+", mm(-981273891273, +999999999), false}, + {"valid +/+", mm(981273891273, 999999999), true}, + {"invalid +/-", mm(981273891273, -999999999), false}, + {"invalid +/+overflow", mm(3, 1000000000), false}, + {"invalid +/-overflow", mm(3, -1000000000), false}, + {"invalid -/+overflow", mm(-3, 1000000000), false}, + {"invalid -/-overflow", mm(-3, -1000000000), false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsValid(tt.in); got != tt.want { + t.Errorf("IsValid(%v) = %v, want %v", tt.in, got, tt.want) + } + }) + } +} + +func TestIsZero(t *testing.T) { + tests := []struct { + name string + in pb.Money + want bool + }{ + {"zero", mm(0, 0), true}, + {"not-zero (-/+)", mm(-1, +1), false}, + {"not-zero (-/-)", mm(-1, -1), false}, + {"not-zero (+/+)", mm(+1, +1), false}, + {"not-zero (+/-)", mm(+1, -1), false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsZero(tt.in); got != tt.want { + t.Errorf("IsZero(%v) = %v, want %v", tt.in, got, tt.want) + } + }) + } +} + +func TestIsPositive(t *testing.T) { + tests := []struct { + name string + in pb.Money + want bool + }{ + {"zero", mm(0, 0), false}, + {"positive (+/+)", mm(+1, +1), true}, + {"invalid (-/+)", mm(-1, +1), false}, + {"negative (-/-)", mm(-1, -1), false}, + {"invalid (+/-)", mm(+1, -1), false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsPositive(tt.in); got != tt.want { + t.Errorf("IsPositive(%v) = %v, want %v", tt.in, got, tt.want) + } + }) + } +} + +func TestIsNegative(t *testing.T) { + tests := []struct { + name string + in pb.Money + want bool + }{ + {"zero", mm(0, 0), false}, + {"positive (+/+)", mm(+1, +1), false}, + {"invalid (-/+)", mm(-1, +1), false}, + {"negative (-/-)", mm(-1, -1), true}, + {"invalid (+/-)", mm(+1, -1), false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsNegative(tt.in); got != tt.want { + t.Errorf("IsNegative(%v) = %v, want %v", tt.in, got, tt.want) + } + }) + } +} + +func TestAreSameCurrency(t *testing.T) { + type args struct { + l pb.Money + r pb.Money + } + tests := []struct { + name string + args args + want bool + }{ + {"both empty currency", args{mmc(1, 0, ""), mmc(2, 0, "")}, false}, + {"left empty currency", args{mmc(1, 0, ""), mmc(2, 0, "USD")}, false}, + {"right empty currency", args{mmc(1, 0, "USD"), mmc(2, 0, "")}, false}, + {"mismatching", args{mmc(1, 0, "USD"), mmc(2, 0, "CAD")}, false}, + {"matching", args{mmc(1, 0, "USD"), mmc(2, 0, "USD")}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := AreSameCurrency(tt.args.l, tt.args.r); got != tt.want { + t.Errorf("AreSameCurrency([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) + } + }) + } +} + +func TestAreEquals(t *testing.T) { + type args struct { + l pb.Money + r pb.Money + } + tests := []struct { + name string + args args + want bool + }{ + {"equals", args{mmc(1, 2, "USD"), mmc(1, 2, "USD")}, true}, + {"mismatching currency", args{mmc(1, 2, "USD"), mmc(1, 2, "CAD")}, false}, + {"mismatching units", args{mmc(10, 20, "USD"), mmc(1, 20, "USD")}, false}, + {"mismatching nanos", args{mmc(1, 2, "USD"), mmc(1, 20, "USD")}, false}, + {"negated", args{mmc(1, 2, "USD"), mmc(-1, -2, "USD")}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := AreEquals(tt.args.l, tt.args.r); got != tt.want { + t.Errorf("AreEquals([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) + } + }) + } +} + +func TestNegate(t *testing.T) { + tests := []struct { + name string + in pb.Money + want pb.Money + }{ + {"zero", mm(0, 0), mm(0, 0)}, + {"negative", mm(-1, -200), mm(1, 200)}, + {"positive", mm(1, 200), mm(-1, -200)}, + {"carries currency code", mmc(0, 0, "XXX"), mmc(0, 0, "XXX")}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Negate(tt.in); !AreEquals(got, tt.want) { + t.Errorf("Negate([%v]) = %v, want %v", tt.in, got, tt.want) + } + }) + } +} + +func TestMust_pass(t *testing.T) { + v := Must(mm(2, 3), nil) + if !AreEquals(v, mm(2, 3)) { + t.Errorf("returned the wrong value: %v", v) + } +} + +func TestMust_panic(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Logf("panic captured: %v", r) + } + }() + Must(mm(2, 3), fmt.Errorf("some error")) + t.Fatal("this should not have executed due to the panic above") +} + +func TestSum(t *testing.T) { + type args struct { + l pb.Money + r pb.Money + } + tests := []struct { + name string + args args + want pb.Money + wantErr error + }{ + {"0+0=0", args{mm(0, 0), mm(0, 0)}, mm(0, 0), nil}, + {"Error: currency code on left", args{mmc(0, 0, "XXX"), mm(0, 0)}, mm(0, 0), ErrMismatchingCurrency}, + {"Error: currency code on right", args{mm(0, 0), mmc(0, 0, "YYY")}, mm(0, 0), ErrMismatchingCurrency}, + {"Error: currency code mismatch", args{mmc(0, 0, "AAA"), mmc(0, 0, "BBB")}, mm(0, 0), ErrMismatchingCurrency}, + {"Error: invalid +/-", args{mm(+1, -1), mm(0, 0)}, mm(0, 0), ErrInvalidValue}, + {"Error: invalid -/+", args{mm(0, 0), mm(-1, +2)}, mm(0, 0), ErrInvalidValue}, + {"Error: invalid nanos", args{mm(0, 1000000000), mm(1, 0)}, mm(0, 0), ErrInvalidValue}, + {"both positive (no carry)", args{mm(2, 200000000), mm(2, 200000000)}, mm(4, 400000000), nil}, + {"both positive (nanos=max)", args{mm(2, 111111111), mm(2, 888888888)}, mm(4, 999999999), nil}, + {"both positive (carry)", args{mm(2, 200000000), mm(2, 900000000)}, mm(5, 100000000), nil}, + {"both negative (no carry)", args{mm(-2, -200000000), mm(-2, -200000000)}, mm(-4, -400000000), nil}, + {"both negative (carry)", args{mm(-2, -200000000), mm(-2, -900000000)}, mm(-5, -100000000), nil}, + {"mixed (larger positive, just decimals)", args{mm(11, 0), mm(-2, 0)}, mm(9, 0), nil}, + {"mixed (larger negative, just decimals)", args{mm(-11, 0), mm(2, 0)}, mm(-9, 0), nil}, + {"mixed (larger positive, no borrow)", args{mm(11, 100000000), mm(-2, -100000000)}, mm(9, 0), nil}, + {"mixed (larger positive, with borrow)", args{mm(11, 100000000), mm(-2, -9000000 /*.09*/)}, mm(9, 91000000 /*.091*/), nil}, + {"mixed (larger negative, no borrow)", args{mm(-11, -100000000), mm(2, 100000000)}, mm(-9, 0), nil}, + {"mixed (larger negative, with borrow)", args{mm(-11, -100000000), mm(2, 9000000 /*.09*/)}, mm(-9, -91000000 /*.091*/), nil}, + {"0+negative", args{mm(0, 0), mm(-2, -100000000)}, mm(-2, -100000000), nil}, + {"negative+0", args{mm(-2, -100000000), mm(0, 0)}, mm(-2, -100000000), nil}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Sum(tt.args.l, tt.args.r) + if err != tt.wantErr { + t.Errorf("Sum([%v],[%v]): expected err=\"%v\" got=\"%v\"", tt.args.l, tt.args.r, tt.wantErr, err) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Sum([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want) + } + }) + } +} From 9a96b73cf1926068bc1fcd5af4df42948577acf9 Mon Sep 17 00:00:00 2001 From: Andrew Tate Date: Thu, 6 Apr 2023 10:34:12 -0400 Subject: [PATCH 2/4] Update skaffold.yaml --- skaffold.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/skaffold.yaml b/skaffold.yaml index 195f062..d9a4f0a 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -2,10 +2,10 @@ apiVersion: skaffold/v1beta2 kind: Config build: artifacts: - # image tags are relative; to specify an image repo (e.g. GCR), you - # must provide a "default repo" using one of the methods described - # here: - # https://skaffold.dev/docs/concepts/#image-repository-handling + # image tags are relative; to specify an image repo (e.g. GCR), you + # must provide a "default repo" using one of the methods described + # here: + # https://skaffold.dev/docs/concepts/#image-repository-handling - image: adservice context: src/adservice - image: cartservice @@ -28,6 +28,8 @@ build: context: src/recommendationservice - image: shippingservice context: src/shippingservice + - image: restservice + context: src/restservice tagPolicy: gitCommit: {} local: @@ -36,4 +38,3 @@ deploy: kubectl: manifests: - ./kubernetes-manifests/**.yaml - From 7e42ce8192f609733c61c56d1f6bfc9b00019599 Mon Sep 17 00:00:00 2001 From: Andrew Tate Date: Thu, 6 Apr 2023 10:34:15 -0400 Subject: [PATCH 3/4] Create restservice.yaml --- kubernetes-manifests/restservice.yaml | 68 +++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 kubernetes-manifests/restservice.yaml diff --git a/kubernetes-manifests/restservice.yaml b/kubernetes-manifests/restservice.yaml new file mode 100644 index 0000000..093611f --- /dev/null +++ b/kubernetes-manifests/restservice.yaml @@ -0,0 +1,68 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: restservice +spec: + selector: + matchLabels: + app: restservice + template: + metadata: + labels: + app: restservice + annotations: + sidecar.signadot.com/inject: rest + spec: + serviceAccountName: default + containers: + - name: server + image: restservice + ports: + - containerPort: 5051 + # readinessProbe: + # exec: + # command: ["/bin/grpc_health_probe", "-addr=:5050"] + # livenessProbe: + # exec: + # command: ["/bin/grpc_health_probe", "-addr=:5050"] + env: + - name: PORT + value: "5051" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "productcatalogservice:3550" + - name: SHIPPING_SERVICE_ADDR + value: "shippingservice:50051" + - name: PAYMENT_SERVICE_ADDR + value: "paymentservice:50051" + - name: EMAIL_SERVICE_ADDR + value: "emailservice:5000" + - name: CURRENCY_SERVICE_ADDR + value: "currencyservice:7000" + - name: CART_SERVICE_ADDR + value: "cartservice:7070" + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CACHE_USER_THRESHOLD + value: "35000" + resources: + requests: + cpu: 100m + memory: 32Mi + limits: + cpu: 200m + memory: 32Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: restservice +spec: + type: ClusterIP + selector: + app: restservice + ports: + - name: rest + port: 5051 + targetPort: 5051 From f651282ec97c92bdc320b97c6eda278e5ddd7274 Mon Sep 17 00:00:00 2001 From: Andrew Tate Date: Thu, 6 Apr 2023 10:36:13 -0400 Subject: [PATCH 4/4] Create sandbox-rest.yaml --- .signadot/sandbox-rest.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .signadot/sandbox-rest.yaml diff --git a/.signadot/sandbox-rest.yaml b/.signadot/sandbox-rest.yaml new file mode 100644 index 0000000..2265647 --- /dev/null +++ b/.signadot/sandbox-rest.yaml @@ -0,0 +1,20 @@ +name: "@{name}" +spec: + description: Adds REST API to the baseline sandbox + cluster: ms-cluster + labels: + branch: "rest" + forks: + - forkOf: + kind: Deployment + name: restservice + namespace: default + customizations: + images: + - image: {docker_username}/{docker_repo}:@{rest-tag} + defaultRouteGroup: # CLI v0.3.7+ required (see sandbox specification for details) + endpoints: + - name: rest-endpoint + target: http://restservice.default.svc:5051 + - name: frontend-endpoint + target: http://frontend.default.svc:80