diff --git a/ch02/productinfo/java/client/build.gradle b/ch02/productinfo/java/client/build.gradle index 15b3ec4..73b82d3 100644 --- a/ch02/productinfo/java/client/build.gradle +++ b/ch02/productinfo/java/client/build.gradle @@ -12,7 +12,7 @@ def grpcVersion = '1.39.0' compile "io.grpc:grpc-protobuf:${grpcVersion}" compile "io.grpc:grpc-stub:${grpcVersion}" compile 'com.google.protobuf:protobuf-java:3.17.2' - compile 'javax.annotation:javax.annotation-api:1.2' + compile 'javax.annotation:javax.annotation-api:1.3.2' } buildscript { diff --git a/ch02/productinfo/java/server/build.gradle b/ch02/productinfo/java/server/build.gradle index 3334989..6a54832 100644 --- a/ch02/productinfo/java/server/build.gradle +++ b/ch02/productinfo/java/server/build.gradle @@ -12,7 +12,7 @@ dependencies { compile "io.grpc:grpc-protobuf:${grpcVersion}" compile "io.grpc:grpc-stub:${grpcVersion}" compile 'com.google.protobuf:protobuf-java:3.17.2' - compile 'javax.annotation:javax.annotation-api:1.2' + compile 'javax.annotation:javax.annotation-api:1.3.2' } buildscript { diff --git a/ch03/README.md b/ch03/README.md index 1d7ef8c..790481c 100644 --- a/ch03/README.md +++ b/ch03/README.md @@ -41,6 +41,7 @@ message CombinedShipment { - [Go](./order-service/go/README.md) - [Java](./order-service/java/README.md) +- [Python](./order-service/python/README.md) diff --git a/ch03/order-service/go/client/main.go b/ch03/order-service/go/client/main.go index 1f73437..ea724a6 100644 --- a/ch03/order-service/go/client/main.go +++ b/ch03/order-service/go/client/main.go @@ -2,10 +2,11 @@ package main import ( "context" - "google.golang.org/grpc" "log" pb "ordermgt/client/ecommerce" "time" + + "google.golang.org/grpc" ) const ( @@ -19,8 +20,8 @@ func main() { log.Fatalf("did not connect: %v", err) } defer conn.Close() - client := pb.NewOrderManagementClient(conn) - ctx , cancel := context.WithTimeout(context.Background(), time.Second*5) + client := pb.NewOrderManagementClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() // Add Order @@ -110,7 +111,7 @@ func main() { // if err := streamProcOrder.CloseSend(); err != nil { // log.Fatal(err) // } - // <- channel + // channel <- struct{}{} } //func asncClientBidirectionalRPC(streamProcOrder pb.OrderManagement_ProcessOrdersClient, c chan struct{}) { diff --git a/ch03/order-service/go/service/README.md b/ch03/order-service/go/service/README.md deleted file mode 100644 index fd40910..0000000 --- a/ch03/order-service/go/service/README.md +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/ch03/order-service/proto/order_management.proto b/ch03/order-service/proto/order_management.proto index 50c520a..f1aa315 100644 --- a/ch03/order-service/proto/order_management.proto +++ b/ch03/order-service/proto/order_management.proto @@ -1,4 +1,3 @@ -// Deprecated !!!! syntax = "proto3"; import "google/protobuf/wrappers.proto"; diff --git a/ch03/order-service/python/README.md b/ch03/order-service/python/README.md new file mode 100644 index 0000000..1378a0f --- /dev/null +++ b/ch03/order-service/python/README.md @@ -0,0 +1,43 @@ +## ``OrderManagement`` Service and Client - Python Implementation + +## Prerequisites +- Python 3.5 or higher +- pip version 9.0.1 or higher + +If necessary, upgrade your version of pip: +``` +python -m pip install --upgrade pip +``` + +Install gRPC and gRPC tools + +``` +python -m pip install --upgrade pip +python -m pip install grpcio +python -m pip install grpcio-tools + +``` + +## Code Generation + +Generate Python code by pointing to the .proto file. + +``` +python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. order_management.proto + +``` + + +## Running the Service +Run the server with: + +``` +python server.py +``` + +## Running the Client + +Run the client with: +``` +python server.py +``` diff --git a/ch03/order-service/python/client/client.py b/ch03/order-service/python/client/client.py new file mode 100644 index 0000000..25eebe0 --- /dev/null +++ b/ch03/order-service/python/client/client.py @@ -0,0 +1,93 @@ +from google.protobuf import wrappers_pb2 +import grpc +import order_management_pb2 +import order_management_pb2_grpc + +import time + + +def run(): + channel = grpc.insecure_channel('localhost:50051') + + + + stub = order_management_pb2_grpc.OrderManagementStub(channel) + + order1 = order_management_pb2.Order(items=['Item - A', 'Item - B', 'Item - C'], + price=2450.50, + description='This is a Sample order - 1 : description.', + destination='San Jose, CA') + + + order = stub.getOrder(order_management_pb2.Order(id='101')) + print("Order service response", order) + + # Unary RPC : Adding an Order + response = stub.addOrder(order1) + print('Add order response :', response) + + # Server Streaming + for order_search_result in stub.searchOrders(wrappers_pb2.StringValue(value='Item - A')): + print('Search Result : ', order_search_result) + + # Client Streaming + upd_order_iterator = generate_orders_for_updates() + upd_status = stub.updateOrders(upd_order_iterator) + print('Order update status : ', upd_status) + + + # Bi-di Streaming + proc_order_iterator = generate_orders_for_processing() + for shipment in stub.processOrders(proc_order_iterator): + print(shipment) + + +def generate_orders_for_updates(): + ord1 = order_management_pb2.Order(id='101', price=1000, + items=['Item - A', 'Item - B', 'Item - C', 'Item - D'], + description='Sample order description.', + destination='Mountain View, CA') + ord2 = order_management_pb2.Order(id='102', price=1000, + items=['Item - E', 'Item - Q', 'Item - R', 'Item - D'], + description='Sample order description.', + destination='San Jose, CA') + ord3 = order_management_pb2.Order(id='103', price=1000, + items=['Item - A', 'Item - K'], + description='Sample order description.', + destination='San Francisco, CA') + list = [] + list.append(ord1) + list.append(ord2) + list.append(ord3) + + for updated_orders in list: + yield updated_orders + +def generate_orders_for_processing(): + ord1 = order_management_pb2.Order( + id='104', price=2332, + items=['Item - A', 'Item - B'], + description='Updated desc', + destination='San Jose, CA') + ord2 = order_management_pb2.Order( + id='105', price=3000, + description='Updated desc', + destination='San Francisco, CA') + ord3 = order_management_pb2.Order( + id='106', price=2560, + description='Updated desc', + destination='San Francisco, CA') + ord4 = order_management_pb2.Order( + id='107', price=2560, + description='Updated desc', + destination='Mountain View, CA') + list = [] + list.append(ord1) + list.append(ord1) + list.append(ord3) + list.append(ord4) + + for processing_orders in list: + yield processing_orders + +run() \ No newline at end of file diff --git a/ch03/order-service/python/client/order_management_pb2.py b/ch03/order-service/python/client/order_management_pb2.py new file mode 100644 index 0000000..a305015 --- /dev/null +++ b/ch03/order-service/python/client/order_management_pb2.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: order_management.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='order_management.proto', + package='ecommerce', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x16order_management.proto\x12\tecommerce\x1a\x1egoogle/protobuf/wrappers.proto\"[\n\x05Order\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05items\x18\x02 \x03(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\r\n\x05price\x18\x04 \x01(\x02\x12\x13\n\x0b\x64\x65stination\x18\x05 \x01(\t\"T\n\x10\x43ombinedShipment\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12$\n\nordersList\x18\x03 \x03(\x0b\x32\x10.ecommerce.Order2\xdd\x02\n\x0fOrderManagement\x12:\n\x08\x61\x64\x64Order\x12\x10.ecommerce.Order\x1a\x1c.google.protobuf.StringValue\x12:\n\x08getOrder\x12\x1c.google.protobuf.StringValue\x1a\x10.ecommerce.Order\x12@\n\x0csearchOrders\x12\x1c.google.protobuf.StringValue\x1a\x10.ecommerce.Order0\x01\x12@\n\x0cupdateOrders\x12\x10.ecommerce.Order\x1a\x1c.google.protobuf.StringValue(\x01\x12N\n\rprocessOrders\x12\x1c.google.protobuf.StringValue\x1a\x1b.ecommerce.CombinedShipment(\x01\x30\x01\x62\x06proto3' + , + dependencies=[google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,]) + + + + +_ORDER = _descriptor.Descriptor( + name='Order', + full_name='ecommerce.Order', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='ecommerce.Order.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='items', full_name='ecommerce.Order.items', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='description', full_name='ecommerce.Order.description', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='price', full_name='ecommerce.Order.price', index=3, + number=4, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='destination', full_name='ecommerce.Order.destination', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=69, + serialized_end=160, +) + + +_COMBINEDSHIPMENT = _descriptor.Descriptor( + name='CombinedShipment', + full_name='ecommerce.CombinedShipment', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='ecommerce.CombinedShipment.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='status', full_name='ecommerce.CombinedShipment.status', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ordersList', full_name='ecommerce.CombinedShipment.ordersList', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=162, + serialized_end=246, +) + +_COMBINEDSHIPMENT.fields_by_name['ordersList'].message_type = _ORDER +DESCRIPTOR.message_types_by_name['Order'] = _ORDER +DESCRIPTOR.message_types_by_name['CombinedShipment'] = _COMBINEDSHIPMENT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Order = _reflection.GeneratedProtocolMessageType('Order', (_message.Message,), { + 'DESCRIPTOR' : _ORDER, + '__module__' : 'order_management_pb2' + # @@protoc_insertion_point(class_scope:ecommerce.Order) + }) +_sym_db.RegisterMessage(Order) + +CombinedShipment = _reflection.GeneratedProtocolMessageType('CombinedShipment', (_message.Message,), { + 'DESCRIPTOR' : _COMBINEDSHIPMENT, + '__module__' : 'order_management_pb2' + # @@protoc_insertion_point(class_scope:ecommerce.CombinedShipment) + }) +_sym_db.RegisterMessage(CombinedShipment) + + + +_ORDERMANAGEMENT = _descriptor.ServiceDescriptor( + name='OrderManagement', + full_name='ecommerce.OrderManagement', + file=DESCRIPTOR, + index=0, + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_start=249, + serialized_end=598, + methods=[ + _descriptor.MethodDescriptor( + name='addOrder', + full_name='ecommerce.OrderManagement.addOrder', + index=0, + containing_service=None, + input_type=_ORDER, + output_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='getOrder', + full_name='ecommerce.OrderManagement.getOrder', + index=1, + containing_service=None, + input_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + output_type=_ORDER, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='searchOrders', + full_name='ecommerce.OrderManagement.searchOrders', + index=2, + containing_service=None, + input_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + output_type=_ORDER, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='updateOrders', + full_name='ecommerce.OrderManagement.updateOrders', + index=3, + containing_service=None, + input_type=_ORDER, + output_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='processOrders', + full_name='ecommerce.OrderManagement.processOrders', + index=4, + containing_service=None, + input_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + output_type=_COMBINEDSHIPMENT, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), +]) +_sym_db.RegisterServiceDescriptor(_ORDERMANAGEMENT) + +DESCRIPTOR.services_by_name['OrderManagement'] = _ORDERMANAGEMENT + +# @@protoc_insertion_point(module_scope) diff --git a/ch03/order-service/python/client/order_management_pb2_grpc.py b/ch03/order-service/python/client/order_management_pb2_grpc.py new file mode 100644 index 0000000..8b03ac8 --- /dev/null +++ b/ch03/order-service/python/client/order_management_pb2_grpc.py @@ -0,0 +1,199 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 +import order_management_pb2 as order__management__pb2 + + +class OrderManagementStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.addOrder = channel.unary_unary( + '/ecommerce.OrderManagement/addOrder', + request_serializer=order__management__pb2.Order.SerializeToString, + response_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + ) + self.getOrder = channel.unary_unary( + '/ecommerce.OrderManagement/getOrder', + request_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + response_deserializer=order__management__pb2.Order.FromString, + ) + self.searchOrders = channel.unary_stream( + '/ecommerce.OrderManagement/searchOrders', + request_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + response_deserializer=order__management__pb2.Order.FromString, + ) + self.updateOrders = channel.stream_unary( + '/ecommerce.OrderManagement/updateOrders', + request_serializer=order__management__pb2.Order.SerializeToString, + response_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + ) + self.processOrders = channel.stream_stream( + '/ecommerce.OrderManagement/processOrders', + request_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + response_deserializer=order__management__pb2.CombinedShipment.FromString, + ) + + +class OrderManagementServicer(object): + """Missing associated documentation comment in .proto file.""" + + def addOrder(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def getOrder(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def searchOrders(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def updateOrders(self, request_iterator, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def processOrders(self, request_iterator, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OrderManagementServicer_to_server(servicer, server): + rpc_method_handlers = { + 'addOrder': grpc.unary_unary_rpc_method_handler( + servicer.addOrder, + request_deserializer=order__management__pb2.Order.FromString, + response_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + ), + 'getOrder': grpc.unary_unary_rpc_method_handler( + servicer.getOrder, + request_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + response_serializer=order__management__pb2.Order.SerializeToString, + ), + 'searchOrders': grpc.unary_stream_rpc_method_handler( + servicer.searchOrders, + request_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + response_serializer=order__management__pb2.Order.SerializeToString, + ), + 'updateOrders': grpc.stream_unary_rpc_method_handler( + servicer.updateOrders, + request_deserializer=order__management__pb2.Order.FromString, + response_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + ), + 'processOrders': grpc.stream_stream_rpc_method_handler( + servicer.processOrders, + request_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + response_serializer=order__management__pb2.CombinedShipment.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'ecommerce.OrderManagement', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class OrderManagement(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def addOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/ecommerce.OrderManagement/addOrder', + order__management__pb2.Order.SerializeToString, + google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def getOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/ecommerce.OrderManagement/getOrder', + google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + order__management__pb2.Order.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def searchOrders(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/ecommerce.OrderManagement/searchOrders', + google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + order__management__pb2.Order.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def updateOrders(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_unary(request_iterator, target, '/ecommerce.OrderManagement/updateOrders', + order__management__pb2.Order.SerializeToString, + google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def processOrders(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_stream(request_iterator, target, '/ecommerce.OrderManagement/processOrders', + google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + order__management__pb2.CombinedShipment.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/ch03/order-service/python/server/order_management_pb2.py b/ch03/order-service/python/server/order_management_pb2.py new file mode 100644 index 0000000..a305015 --- /dev/null +++ b/ch03/order-service/python/server/order_management_pb2.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: order_management.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='order_management.proto', + package='ecommerce', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x16order_management.proto\x12\tecommerce\x1a\x1egoogle/protobuf/wrappers.proto\"[\n\x05Order\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05items\x18\x02 \x03(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\r\n\x05price\x18\x04 \x01(\x02\x12\x13\n\x0b\x64\x65stination\x18\x05 \x01(\t\"T\n\x10\x43ombinedShipment\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12$\n\nordersList\x18\x03 \x03(\x0b\x32\x10.ecommerce.Order2\xdd\x02\n\x0fOrderManagement\x12:\n\x08\x61\x64\x64Order\x12\x10.ecommerce.Order\x1a\x1c.google.protobuf.StringValue\x12:\n\x08getOrder\x12\x1c.google.protobuf.StringValue\x1a\x10.ecommerce.Order\x12@\n\x0csearchOrders\x12\x1c.google.protobuf.StringValue\x1a\x10.ecommerce.Order0\x01\x12@\n\x0cupdateOrders\x12\x10.ecommerce.Order\x1a\x1c.google.protobuf.StringValue(\x01\x12N\n\rprocessOrders\x12\x1c.google.protobuf.StringValue\x1a\x1b.ecommerce.CombinedShipment(\x01\x30\x01\x62\x06proto3' + , + dependencies=[google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,]) + + + + +_ORDER = _descriptor.Descriptor( + name='Order', + full_name='ecommerce.Order', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='ecommerce.Order.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='items', full_name='ecommerce.Order.items', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='description', full_name='ecommerce.Order.description', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='price', full_name='ecommerce.Order.price', index=3, + number=4, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='destination', full_name='ecommerce.Order.destination', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=69, + serialized_end=160, +) + + +_COMBINEDSHIPMENT = _descriptor.Descriptor( + name='CombinedShipment', + full_name='ecommerce.CombinedShipment', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='ecommerce.CombinedShipment.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='status', full_name='ecommerce.CombinedShipment.status', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ordersList', full_name='ecommerce.CombinedShipment.ordersList', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=162, + serialized_end=246, +) + +_COMBINEDSHIPMENT.fields_by_name['ordersList'].message_type = _ORDER +DESCRIPTOR.message_types_by_name['Order'] = _ORDER +DESCRIPTOR.message_types_by_name['CombinedShipment'] = _COMBINEDSHIPMENT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Order = _reflection.GeneratedProtocolMessageType('Order', (_message.Message,), { + 'DESCRIPTOR' : _ORDER, + '__module__' : 'order_management_pb2' + # @@protoc_insertion_point(class_scope:ecommerce.Order) + }) +_sym_db.RegisterMessage(Order) + +CombinedShipment = _reflection.GeneratedProtocolMessageType('CombinedShipment', (_message.Message,), { + 'DESCRIPTOR' : _COMBINEDSHIPMENT, + '__module__' : 'order_management_pb2' + # @@protoc_insertion_point(class_scope:ecommerce.CombinedShipment) + }) +_sym_db.RegisterMessage(CombinedShipment) + + + +_ORDERMANAGEMENT = _descriptor.ServiceDescriptor( + name='OrderManagement', + full_name='ecommerce.OrderManagement', + file=DESCRIPTOR, + index=0, + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_start=249, + serialized_end=598, + methods=[ + _descriptor.MethodDescriptor( + name='addOrder', + full_name='ecommerce.OrderManagement.addOrder', + index=0, + containing_service=None, + input_type=_ORDER, + output_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='getOrder', + full_name='ecommerce.OrderManagement.getOrder', + index=1, + containing_service=None, + input_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + output_type=_ORDER, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='searchOrders', + full_name='ecommerce.OrderManagement.searchOrders', + index=2, + containing_service=None, + input_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + output_type=_ORDER, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='updateOrders', + full_name='ecommerce.OrderManagement.updateOrders', + index=3, + containing_service=None, + input_type=_ORDER, + output_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='processOrders', + full_name='ecommerce.OrderManagement.processOrders', + index=4, + containing_service=None, + input_type=google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE, + output_type=_COMBINEDSHIPMENT, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), +]) +_sym_db.RegisterServiceDescriptor(_ORDERMANAGEMENT) + +DESCRIPTOR.services_by_name['OrderManagement'] = _ORDERMANAGEMENT + +# @@protoc_insertion_point(module_scope) diff --git a/ch03/order-service/python/server/order_management_pb2_grpc.py b/ch03/order-service/python/server/order_management_pb2_grpc.py new file mode 100644 index 0000000..8b03ac8 --- /dev/null +++ b/ch03/order-service/python/server/order_management_pb2_grpc.py @@ -0,0 +1,199 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 +import order_management_pb2 as order__management__pb2 + + +class OrderManagementStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.addOrder = channel.unary_unary( + '/ecommerce.OrderManagement/addOrder', + request_serializer=order__management__pb2.Order.SerializeToString, + response_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + ) + self.getOrder = channel.unary_unary( + '/ecommerce.OrderManagement/getOrder', + request_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + response_deserializer=order__management__pb2.Order.FromString, + ) + self.searchOrders = channel.unary_stream( + '/ecommerce.OrderManagement/searchOrders', + request_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + response_deserializer=order__management__pb2.Order.FromString, + ) + self.updateOrders = channel.stream_unary( + '/ecommerce.OrderManagement/updateOrders', + request_serializer=order__management__pb2.Order.SerializeToString, + response_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + ) + self.processOrders = channel.stream_stream( + '/ecommerce.OrderManagement/processOrders', + request_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + response_deserializer=order__management__pb2.CombinedShipment.FromString, + ) + + +class OrderManagementServicer(object): + """Missing associated documentation comment in .proto file.""" + + def addOrder(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def getOrder(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def searchOrders(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def updateOrders(self, request_iterator, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def processOrders(self, request_iterator, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OrderManagementServicer_to_server(servicer, server): + rpc_method_handlers = { + 'addOrder': grpc.unary_unary_rpc_method_handler( + servicer.addOrder, + request_deserializer=order__management__pb2.Order.FromString, + response_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + ), + 'getOrder': grpc.unary_unary_rpc_method_handler( + servicer.getOrder, + request_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + response_serializer=order__management__pb2.Order.SerializeToString, + ), + 'searchOrders': grpc.unary_stream_rpc_method_handler( + servicer.searchOrders, + request_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + response_serializer=order__management__pb2.Order.SerializeToString, + ), + 'updateOrders': grpc.stream_unary_rpc_method_handler( + servicer.updateOrders, + request_deserializer=order__management__pb2.Order.FromString, + response_serializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + ), + 'processOrders': grpc.stream_stream_rpc_method_handler( + servicer.processOrders, + request_deserializer=google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + response_serializer=order__management__pb2.CombinedShipment.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'ecommerce.OrderManagement', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class OrderManagement(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def addOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/ecommerce.OrderManagement/addOrder', + order__management__pb2.Order.SerializeToString, + google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def getOrder(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/ecommerce.OrderManagement/getOrder', + google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + order__management__pb2.Order.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def searchOrders(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/ecommerce.OrderManagement/searchOrders', + google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + order__management__pb2.Order.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def updateOrders(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_unary(request_iterator, target, '/ecommerce.OrderManagement/updateOrders', + order__management__pb2.Order.SerializeToString, + google_dot_protobuf_dot_wrappers__pb2.StringValue.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def processOrders(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_stream(request_iterator, target, '/ecommerce.OrderManagement/processOrders', + google_dot_protobuf_dot_wrappers__pb2.StringValue.SerializeToString, + order__management__pb2.CombinedShipment.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/ch03/order-service/python/server/server.py b/ch03/order-service/python/server/server.py new file mode 100644 index 0000000..87ee2d7 --- /dev/null +++ b/ch03/order-service/python/server/server.py @@ -0,0 +1,97 @@ +from concurrent import futures +import time +from typing import OrderedDict +import uuid +from google.protobuf import wrappers_pb2 + +import grpc +import order_management_pb2_grpc +import order_management_pb2 + +class OrderManagementServicer(order_management_pb2_grpc.OrderManagementServicer): + + def __init__(self): + self.orderDict = {} + #Add a sample order + self.orderDict['101'] = order_management_pb2.Order(id='101', price=1000, + items=['Item - A', 'Item - B'], + description='Sample order description.') + self.orderDict['102'] = order_management_pb2.Order(id='102', price=1000, + items=['Item - C'], + description='Sample order description.') + self.orderDict['103'] = order_management_pb2.Order(id='103', price=1000, + items=['Item - A', 'Item - E'], + description='Sample order description.') + self.orderDict['104'] = order_management_pb2.Order(id='104', price=1000, + items=['Item - F', 'Item - G'], + description='Sample order description.') + + # Unary RPC + def getOrder(self, request, context): + order = self.orderDict.get(request.value) + if order is not None: + return order + else: + # Error handling + print('Order not found ' + request.value) + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details('Order : ', request.value, ' Not Found.') + return order_management_pb2.Order() + + # Unary RPC + def addOrder(self, request, context): + id = uuid.uuid1() + request.id = str(id) + self.orderDict[request.id] = request + response = wrappers_pb2.StringValue(value=str(id)) + print(self.orderDict) + return response + + # Server Streaming + def searchOrders(self, request, context): + matching_orders = self.searchInventory(request.value) + for order in matching_orders: + yield order + + # Client Streaming + def updateOrders(self, request_iterator, context): + response = 'Updated IDs :' + for order in request_iterator: + self.orderDict[order.id] = order + response += ' ' + order.id + return wrappers_pb2.StringValue(value=response) + + + #Bi-di Streaming + def processOrders(self, request_iterator, context): + print('Processing orders.. ') + shipment_id = uuid.uuid1() + shipments = [] + + shipment = order_management_pb2.CombinedShipment(id=str(shipment_id), status='PROCESSED', ) + shipments.append(shipment) + for order_id in request_iterator: + for order in shipments: + yield order + + # Local function + def searchInventory(self, query): + matchingOrders = [] + for order_id, order in self.orderDict.items(): + for itm in order.items: + if query in itm: + matchingOrders.append(order) + break + return matchingOrders + + +# Creating gRPC Server +server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) +order_management_pb2_grpc.add_OrderManagementServicer_to_server(OrderManagementServicer(), server) +print('Starting server. Listening on port 50051.') +server.add_insecure_port('[::]:50051') +server.start() +server.wait_for_termination() + + +