Expanded on experimenting with grpc server
diff --git a/Makefile b/Makefile
index b0455d3..a85f749 100644
--- a/Makefile
+++ b/Makefile
@@ -91,6 +91,7 @@
docker pull consul:latest
docker pull fluent/fluentd:latest
docker pull gliderlabs/registrator:latest
+ docker pull ubuntu:xenial
purge-venv:
rm -fr ${VENVDIR}
diff --git a/voltha/core/protos/voltha.desc b/voltha/core/protos/voltha.desc
index fdd58f5..d22a73b 100644
--- a/voltha/core/protos/voltha.desc
+++ b/voltha/core/protos/voltha.desc
Binary files differ
diff --git a/voltha/core/protos/voltha.proto b/voltha/core/protos/voltha.proto
index 647e4f0..87b6dda 100644
--- a/voltha/core/protos/voltha.proto
+++ b/voltha/core/protos/voltha.proto
@@ -1,5 +1,3 @@
-// See README.txt for information and build instructions.
-
syntax = "proto3";
package voltha;
@@ -28,23 +26,77 @@
}
-// A more complex message type for testing purposes
-message MoreComplex {
- HealthStatus health = 1; // Embedded health
- int32 foo_counter = 2; // Counting foos
- string name = 3; // Name of this thing
- repeated MoreComplex children = 4; // Nested object to test recursion type
-}
-
+// Health related services
service HealthService {
// Return current health status of a Voltha instance
rpc GetHealthStatus(NullMessage) returns (HealthStatus) {
option (google.api.http) = {
get: "/health"
- body: '*'
};
}
}
+// (placeholder) Address as example message
+message Address {
+ string id = 7; // ID of address record
+ string street = 1; // Street address
+ string street2 = 2; // Apartment, suite, building, etc.
+ string street3 = 3; // Apartment, suite, building, etc.
+ string city = 4; // City
+ string state = 5; // State
+ uint32 zip = 6; // Zip code
+}
+
+message Addresses {
+ repeated Address addresses = 1;
+}
+
+// (placeholder) A more complex message type for testing purposes
+message MoreComplex {
+ HealthStatus health = 1; // Embedded health status
+ int32 foo_counter = 2; // Counting foos
+ string name = 3; // Name of this thing
+ repeated MoreComplex children = 4; // Nested object to test recursion type
+ Address address = 5;
+}
+
+// (placeholder) Convey an identifier
+message ID {
+ string id = 1;
+}
+
+// (placeholder) This is an example service
+service ExampleService {
+
+ // Return a bit more complex objects
+ rpc ListAddresses(NullMessage) returns (Addresses) {
+ option (google.api.http) = {
+ get: "/addresses"
+ };
+ }
+
+ // Return an address by ID
+ rpc GetAddress(ID) returns (Address) {
+ option (google.api.http) = {
+ get: "/addresses/{id}"
+ };
+ }
+
+ // Create an address record
+ rpc CreateAddress(Address) returns (Address) {
+ option (google.api.http) = {
+ post: "/addresses"
+ body: "*"
+ };
+ }
+
+ // Delete an address record by ID
+ rpc DeleteAddress(ID) returns (NullMessage) {
+ option (google.api.http) = {
+ delete: "/addresses/{id}"
+ };
+ }
+
+}
diff --git a/voltha/core/protos/voltha_pb2.py b/voltha/core/protos/voltha_pb2.py
index 6337489..176d023 100644
--- a/voltha/core/protos/voltha_pb2.py
+++ b/voltha/core/protos/voltha_pb2.py
@@ -20,7 +20,7 @@
name='voltha.proto',
package='voltha',
syntax='proto3',
- serialized_pb=_b('\n\x0cvoltha.proto\x12\x06voltha\x1a\x1cgoogle/api/annotations.proto\"\r\n\x0bNullMessage\"v\n\x0cHealthStatus\x12/\n\x05state\x18\x01 \x01(\x0e\x32 .voltha.HealthStatus.HealthState\"5\n\x0bHealthState\x12\x0b\n\x07HEALTHY\x10\x00\x12\x0e\n\nOVERLOADED\x10\x01\x12\t\n\x05\x44YING\x10\x02\x32\x61\n\rHealthService\x12P\n\x0fGetHealthStatus\x12\x13.voltha.NullMessage\x1a\x14.voltha.HealthStatus\"\x12\x82\xd3\xe4\x93\x02\x0c\x12\x07/health:\x01*B<\n\x13org.opencord.volthaB\x0cVolthaProtos\xaa\x02\x16Opencord.Voltha.Volthab\x06proto3')
+ serialized_pb=_b('\n\x0cvoltha.proto\x12\x06voltha\x1a\x1cgoogle/api/annotations.proto\"\r\n\x0bNullMessage\"v\n\x0cHealthStatus\x12/\n\x05state\x18\x01 \x01(\x0e\x32 .voltha.HealthStatus.HealthState\"5\n\x0bHealthState\x12\x0b\n\x07HEALTHY\x10\x00\x12\x0e\n\nOVERLOADED\x10\x01\x12\t\n\x05\x44YING\x10\x02\"q\n\x07\x41\x64\x64ress\x12\n\n\x02id\x18\x07 \x01(\t\x12\x0e\n\x06street\x18\x01 \x01(\t\x12\x0f\n\x07street2\x18\x02 \x01(\t\x12\x0f\n\x07street3\x18\x03 \x01(\t\x12\x0c\n\x04\x63ity\x18\x04 \x01(\t\x12\r\n\x05state\x18\x05 \x01(\t\x12\x0b\n\x03zip\x18\x06 \x01(\r\"/\n\tAddresses\x12\"\n\taddresses\x18\x01 \x03(\x0b\x32\x0f.voltha.Address\"\x9f\x01\n\x0bMoreComplex\x12$\n\x06health\x18\x01 \x01(\x0b\x32\x14.voltha.HealthStatus\x12\x13\n\x0b\x66oo_counter\x18\x02 \x01(\x05\x12\x0c\n\x04name\x18\x03 \x01(\t\x12%\n\x08\x63hildren\x18\x04 \x03(\x0b\x32\x13.voltha.MoreComplex\x12 \n\x07\x61\x64\x64ress\x18\x05 \x01(\x0b\x32\x0f.voltha.Address\"\x10\n\x02ID\x12\n\n\x02id\x18\x01 \x01(\t2a\n\rHealthService\x12P\n\x0fGetHealthStatus\x12\x13.voltha.NullMessage\x1a\x14.voltha.HealthStatus\"\x12\x82\xd3\xe4\x93\x02\x0c\x12\x07/health:\x01*2\xb6\x02\n\x0e\x45xampleService\x12K\n\rListAddresses\x12\x13.voltha.NullMessage\x1a\x11.voltha.Addresses\"\x12\x82\xd3\xe4\x93\x02\x0c\x12\n/addresses\x12\x42\n\nGetAddress\x12\n.voltha.ID\x1a\x0f.voltha.Address\"\x17\x82\xd3\xe4\x93\x02\x11\x12\x0f/addresses/{id}\x12H\n\rCreateAddress\x12\x0f.voltha.Address\x1a\x0f.voltha.Address\"\x15\x82\xd3\xe4\x93\x02\x0f\"\n/addresses:\x01*\x12I\n\rDeleteAddress\x12\n.voltha.ID\x1a\x13.voltha.NullMessage\"\x17\x82\xd3\xe4\x93\x02\x11*\x0f/addresses/{id}B<\n\x13org.opencord.volthaB\x0cVolthaProtos\xaa\x02\x16Opencord.Voltha.Volthab\x06proto3')
,
dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,])
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -109,10 +109,212 @@
serialized_end=187,
)
+
+_ADDRESS = _descriptor.Descriptor(
+ name='Address',
+ full_name='voltha.Address',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='id', full_name='voltha.Address.id', index=0,
+ number=7, 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='street', full_name='voltha.Address.street', index=1,
+ 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='street2', full_name='voltha.Address.street2', index=2,
+ 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='street3', full_name='voltha.Address.street3', index=3,
+ 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='city', full_name='voltha.Address.city', index=4,
+ number=4, 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='state', full_name='voltha.Address.state', index=5,
+ 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='zip', full_name='voltha.Address.zip', index=6,
+ number=6, type=13, cpp_type=3, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=189,
+ serialized_end=302,
+)
+
+
+_ADDRESSES = _descriptor.Descriptor(
+ name='Addresses',
+ full_name='voltha.Addresses',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='addresses', full_name='voltha.Addresses.addresses', index=0,
+ number=1, 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,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=304,
+ serialized_end=351,
+)
+
+
+_MORECOMPLEX = _descriptor.Descriptor(
+ name='MoreComplex',
+ full_name='voltha.MoreComplex',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='health', full_name='voltha.MoreComplex.health', index=0,
+ number=1, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='foo_counter', full_name='voltha.MoreComplex.foo_counter', index=1,
+ number=2, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='name', full_name='voltha.MoreComplex.name', 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='children', full_name='voltha.MoreComplex.children', index=3,
+ number=4, 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,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='address', full_name='voltha.MoreComplex.address', index=4,
+ number=5, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=354,
+ serialized_end=513,
+)
+
+
+_ID = _descriptor.Descriptor(
+ name='ID',
+ full_name='voltha.ID',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='id', full_name='voltha.ID.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,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=515,
+ serialized_end=531,
+)
+
_HEALTHSTATUS.fields_by_name['state'].enum_type = _HEALTHSTATUS_HEALTHSTATE
_HEALTHSTATUS_HEALTHSTATE.containing_type = _HEALTHSTATUS
+_ADDRESSES.fields_by_name['addresses'].message_type = _ADDRESS
+_MORECOMPLEX.fields_by_name['health'].message_type = _HEALTHSTATUS
+_MORECOMPLEX.fields_by_name['children'].message_type = _MORECOMPLEX
+_MORECOMPLEX.fields_by_name['address'].message_type = _ADDRESS
DESCRIPTOR.message_types_by_name['NullMessage'] = _NULLMESSAGE
DESCRIPTOR.message_types_by_name['HealthStatus'] = _HEALTHSTATUS
+DESCRIPTOR.message_types_by_name['Address'] = _ADDRESS
+DESCRIPTOR.message_types_by_name['Addresses'] = _ADDRESSES
+DESCRIPTOR.message_types_by_name['MoreComplex'] = _MORECOMPLEX
+DESCRIPTOR.message_types_by_name['ID'] = _ID
NullMessage = _reflection.GeneratedProtocolMessageType('NullMessage', (_message.Message,), dict(
DESCRIPTOR = _NULLMESSAGE,
@@ -128,6 +330,34 @@
))
_sym_db.RegisterMessage(HealthStatus)
+Address = _reflection.GeneratedProtocolMessageType('Address', (_message.Message,), dict(
+ DESCRIPTOR = _ADDRESS,
+ __module__ = 'voltha_pb2'
+ # @@protoc_insertion_point(class_scope:voltha.Address)
+ ))
+_sym_db.RegisterMessage(Address)
+
+Addresses = _reflection.GeneratedProtocolMessageType('Addresses', (_message.Message,), dict(
+ DESCRIPTOR = _ADDRESSES,
+ __module__ = 'voltha_pb2'
+ # @@protoc_insertion_point(class_scope:voltha.Addresses)
+ ))
+_sym_db.RegisterMessage(Addresses)
+
+MoreComplex = _reflection.GeneratedProtocolMessageType('MoreComplex', (_message.Message,), dict(
+ DESCRIPTOR = _MORECOMPLEX,
+ __module__ = 'voltha_pb2'
+ # @@protoc_insertion_point(class_scope:voltha.MoreComplex)
+ ))
+_sym_db.RegisterMessage(MoreComplex)
+
+ID = _reflection.GeneratedProtocolMessageType('ID', (_message.Message,), dict(
+ DESCRIPTOR = _ID,
+ __module__ = 'voltha_pb2'
+ # @@protoc_insertion_point(class_scope:voltha.ID)
+ ))
+_sym_db.RegisterMessage(ID)
+
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023org.opencord.volthaB\014VolthaProtos\252\002\026Opencord.Voltha.Voltha'))
@@ -217,4 +447,189 @@
}
stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
return beta_implementations.dynamic_stub(channel, 'voltha.HealthService', cardinalities, options=stub_options)
+
+
+class ExampleServiceStub(object):
+ """(placeholder) This is an example service
+ """
+
+ def __init__(self, channel):
+ """Constructor.
+
+ Args:
+ channel: A grpc.Channel.
+ """
+ self.ListAddresses = channel.unary_unary(
+ '/voltha.ExampleService/ListAddresses',
+ request_serializer=NullMessage.SerializeToString,
+ response_deserializer=Addresses.FromString,
+ )
+ self.GetAddress = channel.unary_unary(
+ '/voltha.ExampleService/GetAddress',
+ request_serializer=ID.SerializeToString,
+ response_deserializer=Address.FromString,
+ )
+ self.CreateAddress = channel.unary_unary(
+ '/voltha.ExampleService/CreateAddress',
+ request_serializer=Address.SerializeToString,
+ response_deserializer=Address.FromString,
+ )
+ self.DeleteAddress = channel.unary_unary(
+ '/voltha.ExampleService/DeleteAddress',
+ request_serializer=ID.SerializeToString,
+ response_deserializer=NullMessage.FromString,
+ )
+
+
+class ExampleServiceServicer(object):
+ """(placeholder) This is an example service
+ """
+
+ def ListAddresses(self, request, context):
+ """Return a bit more complex objects
+ """
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def GetAddress(self, request, context):
+ """Return an address by ID
+ """
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def CreateAddress(self, request, context):
+ """Create an address record
+ """
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def DeleteAddress(self, request, context):
+ """Delete an address record by ID
+ """
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+def add_ExampleServiceServicer_to_server(servicer, server):
+ rpc_method_handlers = {
+ 'ListAddresses': grpc.unary_unary_rpc_method_handler(
+ servicer.ListAddresses,
+ request_deserializer=NullMessage.FromString,
+ response_serializer=Addresses.SerializeToString,
+ ),
+ 'GetAddress': grpc.unary_unary_rpc_method_handler(
+ servicer.GetAddress,
+ request_deserializer=ID.FromString,
+ response_serializer=Address.SerializeToString,
+ ),
+ 'CreateAddress': grpc.unary_unary_rpc_method_handler(
+ servicer.CreateAddress,
+ request_deserializer=Address.FromString,
+ response_serializer=Address.SerializeToString,
+ ),
+ 'DeleteAddress': grpc.unary_unary_rpc_method_handler(
+ servicer.DeleteAddress,
+ request_deserializer=ID.FromString,
+ response_serializer=NullMessage.SerializeToString,
+ ),
+ }
+ generic_handler = grpc.method_handlers_generic_handler(
+ 'voltha.ExampleService', rpc_method_handlers)
+ server.add_generic_rpc_handlers((generic_handler,))
+
+
+class BetaExampleServiceServicer(object):
+ """(placeholder) This is an example service
+ """
+ def ListAddresses(self, request, context):
+ """Return a bit more complex objects
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+ def GetAddress(self, request, context):
+ """Return an address by ID
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+ def CreateAddress(self, request, context):
+ """Create an address record
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+ def DeleteAddress(self, request, context):
+ """Delete an address record by ID
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+class BetaExampleServiceStub(object):
+ """(placeholder) This is an example service
+ """
+ def ListAddresses(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ """Return a bit more complex objects
+ """
+ raise NotImplementedError()
+ ListAddresses.future = None
+ def GetAddress(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ """Return an address by ID
+ """
+ raise NotImplementedError()
+ GetAddress.future = None
+ def CreateAddress(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ """Create an address record
+ """
+ raise NotImplementedError()
+ CreateAddress.future = None
+ def DeleteAddress(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ """Delete an address record by ID
+ """
+ raise NotImplementedError()
+ DeleteAddress.future = None
+
+
+def beta_create_ExampleService_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+ request_deserializers = {
+ ('voltha.ExampleService', 'CreateAddress'): Address.FromString,
+ ('voltha.ExampleService', 'DeleteAddress'): ID.FromString,
+ ('voltha.ExampleService', 'GetAddress'): ID.FromString,
+ ('voltha.ExampleService', 'ListAddresses'): NullMessage.FromString,
+ }
+ response_serializers = {
+ ('voltha.ExampleService', 'CreateAddress'): Address.SerializeToString,
+ ('voltha.ExampleService', 'DeleteAddress'): NullMessage.SerializeToString,
+ ('voltha.ExampleService', 'GetAddress'): Address.SerializeToString,
+ ('voltha.ExampleService', 'ListAddresses'): Addresses.SerializeToString,
+ }
+ method_implementations = {
+ ('voltha.ExampleService', 'CreateAddress'): face_utilities.unary_unary_inline(servicer.CreateAddress),
+ ('voltha.ExampleService', 'DeleteAddress'): face_utilities.unary_unary_inline(servicer.DeleteAddress),
+ ('voltha.ExampleService', 'GetAddress'): face_utilities.unary_unary_inline(servicer.GetAddress),
+ ('voltha.ExampleService', 'ListAddresses'): face_utilities.unary_unary_inline(servicer.ListAddresses),
+ }
+ server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+ return beta_implementations.server(method_implementations, options=server_options)
+
+
+def beta_create_ExampleService_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+ request_serializers = {
+ ('voltha.ExampleService', 'CreateAddress'): Address.SerializeToString,
+ ('voltha.ExampleService', 'DeleteAddress'): ID.SerializeToString,
+ ('voltha.ExampleService', 'GetAddress'): ID.SerializeToString,
+ ('voltha.ExampleService', 'ListAddresses'): NullMessage.SerializeToString,
+ }
+ response_deserializers = {
+ ('voltha.ExampleService', 'CreateAddress'): Address.FromString,
+ ('voltha.ExampleService', 'DeleteAddress'): NullMessage.FromString,
+ ('voltha.ExampleService', 'GetAddress'): Address.FromString,
+ ('voltha.ExampleService', 'ListAddresses'): Addresses.FromString,
+ }
+ cardinalities = {
+ 'CreateAddress': cardinality.Cardinality.UNARY_UNARY,
+ 'DeleteAddress': cardinality.Cardinality.UNARY_UNARY,
+ 'GetAddress': cardinality.Cardinality.UNARY_UNARY,
+ 'ListAddresses': cardinality.Cardinality.UNARY_UNARY,
+ }
+ stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+ return beta_implementations.dynamic_stub(channel, 'voltha.ExampleService', cardinalities, options=stub_options)
# @@protoc_insertion_point(module_scope)
diff --git a/voltha/northbound/grpc/grpc_client.py b/voltha/northbound/grpc/grpc_client.py
index 3700da5..afb727e 100644
--- a/voltha/northbound/grpc/grpc_client.py
+++ b/voltha/northbound/grpc/grpc_client.py
@@ -23,10 +23,18 @@
def run():
+
channel = grpc.insecure_channel('localhost:50055')
+
+ # Ping health state as an example
stub = voltha_pb2.HealthServiceStub(channel)
- response = stub.GetHealthStatus(voltha_pb2.NullMessage())
- print 'Health state:', response.state
+ res = stub.GetHealthStatus(voltha_pb2.NullMessage())
+ print '\nHealth state:', res.state
+
+ # Try another API
+ stub = voltha_pb2.ExampleServiceStub(channel)
+ res = stub.ListAddresses(voltha_pb2.NullMessage())
+ print '\nExample objects returned:\n', res.addresses
if __name__ == '__main__':
run()
diff --git a/voltha/northbound/grpc/grpc_introspect.py b/voltha/northbound/grpc/grpc_introspect.py
index f0a6877..55e5846 100755
--- a/voltha/northbound/grpc/grpc_introspect.py
+++ b/voltha/northbound/grpc/grpc_introspect.py
@@ -65,30 +65,35 @@
def get_catalog(self):
return self.catalog
- def load_descriptor(self, descriptor_blob, fold_comments=True):
+ def load_descriptor(self, descriptor_blob,
+ fold_comments=True,
+ type_tag_name='_type'):
# decode desciription
file_descriptor_set = descriptor_pb2.FileDescriptorSet()
file_descriptor_set.ParseFromString(descriptor_blob)
- d = self.parse(file_descriptor_set)
+ d = self.parse(file_descriptor_set, type_tag_name=type_tag_name)
for _file in d['file']:
if fold_comments:
self.fold_comments_in(_file)
self.catalog[_file['package']] = _file
- def parse_message(self, m):
+ def parse_message(self, m, type_tag_name=None):
assert isinstance(m, Message)
d = OrderedDict()
for fd, v in m.ListFields():
assert isinstance(fd, FieldDescriptor)
if fd.label in (1, 2):
- d[fd.name] = self.parse(v)
+ d[fd.name] = self.parse(v, type_tag_name)
elif fd.label == 3:
- d[fd.name] = [self.parse(x) for x in v]
+ d[fd.name] = [self.parse(x, type_tag_name) for x in v]
else:
raise InvalidDescriptorError()
+ if type_tag_name is not None:
+ d[type_tag_name] = m.DESCRIPTOR.full_name
+
return d
parser_table = {
@@ -97,9 +102,9 @@
bool: lambda x: x,
}
- def parse(self, o):
+ def parse(self, o, type_tag_name=None):
if isinstance(o, Message):
- return self.parse_message(o)
+ return self.parse_message(o, type_tag_name)
else:
return self.parser_table[type(o)](o)
@@ -170,21 +175,31 @@
print dumps(parser.get_catalog(), indent=4)
# try to see if we can decode binary data into JSON automatically
- def make_mc(name):
- mc = voltha_pb2.MoreComplex()
- mc.name = name
- mc.foo_counter = 123123123
- # mc.health = voltha_pb2.HealthStatus()
- mc.health.state = voltha_pb2.HealthStatus.HEALTHY
+ from random import seed, randint
+ seed(0)
+
+ def make_mc(name, n_children=0):
+ mc = voltha_pb2.MoreComplex(
+ name=name,
+ foo_counter=randint(0, 10000),
+ health=voltha_pb2.HealthStatus(
+ state=voltha_pb2.HealthStatus.OVERLOADED
+ ),
+ address=voltha_pb2.MoreComplex.Address(
+ street='1383 N McDowell Blvd',
+ city='Petaluma',
+ zip=94954,
+ state='CA'
+ ),
+ children=[make_mc('child%d' % (i + 1)) for i in xrange(n_children)]
+ )
return mc
- mc = make_mc('root')
- child1 = mc.
- print dir(mc)
+ mc = make_mc('root', 3)
blob = mc.SerializeToString()
print len(blob), 'bytes'
mc2 = voltha_pb2.MoreComplex()
mc2.ParseFromString(blob)
assert mc == mc2
- print dumps(parser.parse(mc), indent=4)
+ print dumps(parser.parse(mc, type_tag_name='_type'), indent=4)
diff --git a/voltha/northbound/grpc/grpc_server.py b/voltha/northbound/grpc/grpc_server.py
index 166a79d..b965dbf 100644
--- a/voltha/northbound/grpc/grpc_server.py
+++ b/voltha/northbound/grpc/grpc_server.py
@@ -15,6 +15,8 @@
#
"""gRPC server endpoint"""
+import uuid
+
import grpc
from concurrent import futures
from structlog import get_logger
@@ -34,9 +36,48 @@
"""Return current health status of a Voltha instance
"""
log.info('get-health-status', request=request)
- hs = voltha_pb2.HealthStatus()
- hs.state = voltha_pb2.HealthStatus.HEALTHY
- return hs
+ res = voltha_pb2.HealthStatus(
+ state=voltha_pb2.HealthStatus.OVERLOADED # HEALTHY
+ )
+ return res
+
+
+class ExampleService(voltha_pb2.ExampleServiceServicer):
+
+ def __init__(self, thread_pool):
+ from random import randint
+ self.thread_pool = thread_pool
+ self.db = dict((id, voltha_pb2.Address(
+ id=id,
+ street="%d 1st Street" % randint(1, 4000),
+ city="Petaluma",
+ zip=94954,
+ state="CA"
+ )) for id in (uuid.uuid5(uuid.NAMESPACE_OID, str(i)).get_hex()
+ for i in xrange(1000, 1005)))
+
+ def GetAddress(self, request, context):
+ log.info('get-address', request=request)
+ return self.db[request.id]
+
+ def ListAddresses(self, request, context):
+ log.info('list-addresses', request=request)
+ res = voltha_pb2.Addresses(
+ addresses=self.db.values()
+ )
+ return res
+
+ def CreateAddress(self, request, context):
+ log.info('create-address', request=request)
+ id = uuid.uuid4().get_hex()
+ request.id = id
+ self.db[id] = request
+ return request
+
+ def DeleteAddress(self, request, context):
+ log.info('delete-address', request=request)
+ del self.db[request.id]
+ return voltha_pb2.NullMessage()
class VolthaGrpcServer(object):
@@ -49,6 +90,8 @@
voltha_pb2.add_HealthServiceServicer_to_server(
HealthService(self.thread_pool), self.server)
+ voltha_pb2.add_ExampleServiceServicer_to_server(
+ ExampleService(self.thread_pool), self.server)
self.server.add_insecure_port('[::]:%s' % self.port)