diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9af15c665892cade5da812f27a941e9494249c5..fe5642c2b6ab3696429d5676242790c4a973d679 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,18 +8,16 @@ stages: - deploy - funct_test + # include the individual .gitlab-ci.yml of each micro-service include: - - local: '/manifests/.gitlab-ci.yml' +# - local: '/manifests/.gitlab-ci.yml' - local: '/src/monitoring/.gitlab-ci.yml' - - local: '/src/centralizedattackdetector/.gitlab-ci.yml' - - local: '/src/context/.gitlab-ci.yml' - - local: '/src/device/.gitlab-ci.yml' - - local: '/src/service/.gitlab-ci.yml' - - local: '/src/tester_integration/.gitlab-ci.yml' - - local: '/src/tester_functional/.gitlab-ci.yml' - - local: '/src/automation/.gitlab-ci.yml' - - local: '/src/policy/.gitlab-ci.yml' - - local: '/src/l3_distributedattackdetector/.gitlab-ci.yml' - - local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml' - - local: '/src/l3_attackmitigator/.gitlab-ci.yml' +# - local: '/src/centralizedattackdetector/.gitlab-ci.yml' +# - local: '/src/context/.gitlab-ci.yml' +# - local: '/src/device/.gitlab-ci.yml' +# - local: '/src/service/.gitlab-ci.yml' +# - local: '/src/tester_integration/.gitlab-ci.yml' +# - local: '/src/tester_functional/.gitlab-ci.yml' +# - local: '/src/automation/.gitlab-ci.yml' + diff --git a/proto/context.proto b/proto/context.proto index 07d6f4b71688c3c23ac3ce85d38164bc5bf6ee1f..3ff28ad12362ab118cf3e8e78d17e18081185ef2 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package context; -//import "kpi_sample_types.proto"; +import "kpi_sample_types.proto"; service ContextService { rpc ListContextIds (Empty ) returns ( ContextIdList ) {} @@ -243,7 +243,6 @@ message EndPointId { message EndPoint { EndPointId endpoint_id = 1; string endpoint_type = 2; - //repeated kpi_sample_types.KpiSampleType kpi_sample_types = 3; } @@ -258,6 +257,7 @@ message ConfigRule { ConfigActionEnum action = 1; string resource_key = 2; string resource_value = 3; + kpi_sample_types.KpiSampleType kpi_sample_type = 4; } diff --git a/proto/device.proto b/proto/device.proto index b1804b486ea181140fac2bfc86354e2a9530d536..a7f3e44b131908a8931a1ef5257d0261b37537a4 100644 --- a/proto/device.proto +++ b/proto/device.proto @@ -2,19 +2,19 @@ syntax = "proto3"; package device; import "context.proto"; -//import "monitoring.proto"; +import "monitoring.proto"; service DeviceService { rpc AddDevice (context.Device ) returns (context.DeviceId ) {} rpc ConfigureDevice (context.Device ) returns (context.DeviceId ) {} rpc DeleteDevice (context.DeviceId ) returns (context.Empty ) {} rpc GetInitialConfig(context.DeviceId ) returns (context.DeviceConfig) {} - //rpc MonitorDeviceKpi(MonitoringSettings) returns (context.Empty ) {} + rpc MonitorDeviceKpi(MonitoringSettings) returns (context.Empty ) {} } -//message MonitoringSettings { -// monitoring.KpiId kpi_id = 1; -// monitoring.KpiDescriptor kpi_descriptor = 2; -// float sampling_duration_s = 3; -// float sampling_interval_s = 4; -//} +message MonitoringSettings { + monitoring.KpiId kpi_id = 1; + monitoring.KpiDescriptor kpi_descriptor = 2; + float sampling_duration_s = 3; + float sampling_interval_s = 4; +} diff --git a/proto/kpi_sample_types.proto b/proto/kpi_sample_types.proto index c989407cdcc946c27efcf97e0b648530b20dfccd..bc1776b92fc87ec51ecc92dbbfbdcea3fd95a542 100644 --- a/proto/kpi_sample_types.proto +++ b/proto/kpi_sample_types.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -//package kpi_sample_types; +package kpi_sample_types; -//enum KpiSampleType { -// UNKNOWN = 0; -// PACKETS_TRANSMITTED = 101; -// PACKETS_RECEIVED = 102; -// BYTES_TRANSMITTED = 201; -// BYTES_RECEIVED = 202; -//} +enum KpiSampleType { + UNKNOWN = 0; + PACKETS_TRANSMITTED = 101; + PACKETS_RECEIVED = 102; + BYTES_TRANSMITTED = 201; + BYTES_RECEIVED = 202; +} diff --git a/proto/monitoring.proto b/proto/monitoring.proto index c012b330ff65381fecaf04ae9d2f5964480aebf3..4b1b930438045d9199f31de2e408e2c56e91d848 100644 --- a/proto/monitoring.proto +++ b/proto/monitoring.proto @@ -2,68 +2,30 @@ syntax = "proto3"; package monitoring; import "context.proto"; -//import "kpi_sample_types.proto"; +import "kpi_sample_types.proto"; service MonitoringService { - // Old RPCs: - rpc CreateKpi (CreateKpiRequest) returns (KpiId) {} - rpc IncludeKpi (IncludeKpiRequest) returns (context.Empty) {} - rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {} - rpc MonitorDeviceKpi (MonitorDeviceKpiRequest) returns (context.Empty) {} - rpc GetStreamKpi ( KpiId ) returns (stream Kpi) {} - rpc GetInstantKpi ( KpiId ) returns (Kpi) {} - - // New RPCs: - //rpc CreateKpi (KpiDescriptor ) returns (KpiId ) {} - //rpc GetKpiDescriptor(KpiId ) returns (KpiDescriptor) {} - //rpc IncludeKpi (Kpi ) returns (context.Empty) {} - //rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {} - //rpc GetStreamKpi (KpiId ) returns (stream Kpi ) {} - //rpc GetInstantKpi (KpiId ) returns (Kpi ) {} + rpc CreateKpi (KpiDescriptor ) returns (KpiId ) {} + rpc GetKpiDescriptor(KpiId ) returns (KpiDescriptor) {} + rpc IncludeKpi (Kpi ) returns (context.Empty) {} + rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {} + rpc GetStreamKpi (KpiId ) returns (stream Kpi ) {} + rpc GetInstantKpi (KpiId ) returns (Kpi ) {} } -message CreateKpiRequest /*New name: KpiDescriptor*/ { - // Old fields: - string kpiDescription = 1; - context.DeviceId device_id = 2; - KpiSampleType kpi_sample_type = 3; - // context.EndpointId endpoint_id = 4; // others might be added - // context.ServiceId service_id = 5; // for monitoring other - // context.SliceId slice_id = 6; // entities - - // New fields: - //string kpi_description = 1; - //kpi_sample_types.KpiSampleType kpi_sample_type = 2; - //context.DeviceId device_id = 3; - //context.EndPointId endpoint_id = 4; - //context.ServiceId service_id = 5; - ////context.SliceId slice_id = 6; // to be used in future features +message KpiDescriptor { + string kpi_description = 1; + kpi_sample_types.KpiSampleType kpi_sample_type = 2; + context.DeviceId device_id = 3; + context.EndPointId endpoint_id = 4; + context.ServiceId service_id = 5; +// context.SliceId slice_id = 6; } message MonitorKpiRequest{ KpiId kpi_id = 1; - - // Old fields: - uint32 connexion_time_s = 2; - uint32 sample_rate_ms = 3; - - // New fields: - //float sampling_duration_s = 2; - //float sampling_interval_s = 3; -} - -// Message to be removed: -message MonitorDeviceKpiRequest{ - Kpi kpi = 1; - uint32 connexion_time_s = 2; - uint32 sample_rate_ms = 3; -} - -// Message to be removed: -message IncludeKpiRequest{ - KpiId kpi_id = 1; - string time_stamp = 2; - KpiValue kpi_value= 3; + float sampling_duration_s = 2; + float sampling_interval_s = 3; } message KpiId { @@ -73,32 +35,18 @@ message KpiId { message Kpi { KpiId kpi_id = 1; string timestamp = 2; - string kpiDescription = 3; // field to be removed - KpiValue kpi_value = 4; // field to be renumbered to 3 - KpiSampleType kpi_sample_type = 5; // field to be removed - context.DeviceId device_id = 6; // field to be removed - // context.EndpointId endpoint_id = 7; // others might be added // field to be removed - // context.ServiceId service_id = 8; // for monitoring other // field to be removed - // context.SliceId slice_id = 9; // entities // field to be removed + KpiValue kpi_value = 4; } message KpiValue { oneof value { - uint32 intVal = 1; // field to be renamed to int_val - float floatVal = 2; // field to be renamed to float_val - string stringVal = 3; // field to be renamed to str_val - bool boolVal = 4; // field to be renamed to bool_val + uint32 intVal = 1; + float floatVal = 2; + string stringVal = 3; + bool boolVal = 4; } } message KpiList { - repeated Kpi kpiList = 1; // to be renamed to kpi_list -} - -enum KpiSampleType { // to be moved to file "kpi_sample_types.proto" - UNKNOWN = 0; - PACKETS_TRANSMITTED = 101; // others might be added for - PACKETS_RECEIVED = 102; // packet, optical, radio,... - BYTES_TRANSMITTED = 201; - BYTES_RECEIVED = 202; + repeated Kpi kpi_list = 1; } diff --git a/src/common/message_broker/Factory.py b/src/common/message_broker/Factory.py index a2ea36435c717835bf4b7c89c2522878e67074c9..34e030b0e2bd878e75cee8af7ea1b56bc095eb23 100644 --- a/src/common/message_broker/Factory.py +++ b/src/common/message_broker/Factory.py @@ -3,13 +3,13 @@ from typing import Optional, Union from .backend._Backend import _Backend from .backend.BackendEnum import BackendEnum from .backend.inmemory.InMemoryBackend import InMemoryBackend -from .backend.redis.RedisBackend import RedisBackend +# from .backend.redis.RedisBackend import RedisBackend LOGGER = logging.getLogger(__name__) BACKENDS = { BackendEnum.INMEMORY.value: InMemoryBackend, - BackendEnum.REDIS.value: RedisBackend, + # BackendEnum.REDIS.value: RedisBackend, #BackendEnum.KAFKA.value: KafkaBackend, #BackendEnum.RABBITMQ.value: RabbitMQBackend, #BackendEnum.ZEROMQ.value: ZeroMQBackend, diff --git a/src/common/orm/Factory.py b/src/common/orm/Factory.py index 6ef0e11ccdd7b2f0f9e3fde62903fef522cb9f7a..df1df56eec900ea8d6dffce5c1dd1132e0e88eee 100644 --- a/src/common/orm/Factory.py +++ b/src/common/orm/Factory.py @@ -3,13 +3,13 @@ from typing import Optional, Union from .backend._Backend import _Backend from .backend.BackendEnum import BackendEnum from .backend.inmemory.InMemoryBackend import InMemoryBackend -from .backend.redis.RedisBackend import RedisBackend +# from .backend.redis.RedisBackend import RedisBackend LOGGER = logging.getLogger(__name__) BACKENDS = { BackendEnum.INMEMORY.value: InMemoryBackend, - BackendEnum.REDIS.value: RedisBackend, + # BackendEnum.REDIS.value: RedisBackend, #BackendEnum.MONGODB.value: MongoDBBackend, #BackendEnum.RETHINKDB.value: RethinkDBBackend, #BackendEnum.ETCD.value: EtcdBackend, diff --git a/src/context/proto/context_pb2.py b/src/context/proto/context_pb2.py index 8b4848bc33bfb0eba76590c8a3a627b2db84ca9f..658c58897615b33a435c7004d05b0a291abf95b7 100644 --- a/src/context/proto/context_pb2.py +++ b/src/context/proto/context_pb2.py @@ -12,6 +12,7 @@ from google.protobuf import symbol_database as _symbol_database _sym_db = _symbol_database.Default() +from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -20,8 +21,9 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"K\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' -) + serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"K\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\"\x9f\x01\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\x12\x38\n\x0fkpi_sample_type\x18\x04 \x01(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' + , + dependencies=[kpi__sample__types__pb2.DESCRIPTOR,]) _EVENTTYPEENUM = _descriptor.EnumDescriptor( name='EventTypeEnum', @@ -53,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3468, - serialized_end=3574, + serialized_start=3551, + serialized_end=3657, ) _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM) @@ -99,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3577, - serialized_end=3774, + serialized_start=3660, + serialized_end=3857, ) _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM) @@ -130,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3777, - serialized_end=3920, + serialized_start=3860, + serialized_end=4003, ) _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM) @@ -166,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3923, - serialized_end=4052, + serialized_start=4006, + serialized_end=4135, ) _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM) @@ -202,8 +204,8 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4055, - serialized_end=4191, + serialized_start=4138, + serialized_end=4274, ) _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM) @@ -233,8 +235,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4193, - serialized_end=4286, + serialized_start=4276, + serialized_end=4369, ) _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM) @@ -286,8 +288,8 @@ _EMPTY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=26, - serialized_end=33, + serialized_start=50, + serialized_end=57, ) @@ -318,8 +320,8 @@ _UUID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=35, - serialized_end=55, + serialized_start=59, + serialized_end=79, ) @@ -357,8 +359,8 @@ _EVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=57, - serialized_end=127, + serialized_start=81, + serialized_end=151, ) @@ -389,8 +391,8 @@ _CONTEXTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=129, - serialized_end=177, + serialized_start=153, + serialized_end=201, ) @@ -442,8 +444,8 @@ _CONTEXT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=180, - serialized_end=362, + serialized_start=204, + serialized_end=386, ) @@ -474,8 +476,8 @@ _CONTEXTIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=364, - serialized_end=420, + serialized_start=388, + serialized_end=444, ) @@ -506,8 +508,8 @@ _CONTEXTLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=422, - serialized_end=471, + serialized_start=446, + serialized_end=495, ) @@ -545,8 +547,8 @@ _CONTEXTEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=473, - serialized_end=558, + serialized_start=497, + serialized_end=582, ) @@ -584,8 +586,8 @@ _TOPOLOGYID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=560, - serialized_end=650, + serialized_start=584, + serialized_end=674, ) @@ -630,8 +632,8 @@ _TOPOLOGY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=652, - serialized_end=778, + serialized_start=676, + serialized_end=802, ) @@ -662,8 +664,8 @@ _TOPOLOGYIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=780, - serialized_end=839, + serialized_start=804, + serialized_end=863, ) @@ -694,8 +696,8 @@ _TOPOLOGYLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=841, - serialized_end=894, + serialized_start=865, + serialized_end=918, ) @@ -733,8 +735,8 @@ _TOPOLOGYEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=896, - serialized_end=984, + serialized_start=920, + serialized_end=1008, ) @@ -765,8 +767,8 @@ _DEVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=986, - serialized_end=1032, + serialized_start=1010, + serialized_end=1056, ) @@ -832,8 +834,8 @@ _DEVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1035, - serialized_end=1317, + serialized_start=1059, + serialized_end=1341, ) @@ -864,8 +866,8 @@ _DEVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1319, - serialized_end=1376, + serialized_start=1343, + serialized_end=1400, ) @@ -896,8 +898,8 @@ _DEVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1378, - serialized_end=1431, + serialized_start=1402, + serialized_end=1455, ) @@ -928,8 +930,8 @@ _DEVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1433, - serialized_end=1479, + serialized_start=1457, + serialized_end=1503, ) @@ -967,8 +969,8 @@ _DEVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1481, - serialized_end=1563, + serialized_start=1505, + serialized_end=1587, ) @@ -999,8 +1001,8 @@ _LINKID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1565, - serialized_end=1607, + serialized_start=1589, + serialized_end=1631, ) @@ -1038,8 +1040,8 @@ _LINK = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1609, - serialized_end=1697, + serialized_start=1633, + serialized_end=1721, ) @@ -1070,8 +1072,8 @@ _LINKIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1699, - serialized_end=1746, + serialized_start=1723, + serialized_end=1770, ) @@ -1102,8 +1104,8 @@ _LINKLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1748, - serialized_end=1788, + serialized_start=1772, + serialized_end=1812, ) @@ -1141,8 +1143,8 @@ _LINKEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1790, - serialized_end=1866, + serialized_start=1814, + serialized_end=1890, ) @@ -1180,8 +1182,8 @@ _SERVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1868, - serialized_end=1956, + serialized_start=1892, + serialized_end=1980, ) @@ -1247,8 +1249,8 @@ _SERVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1959, - serialized_end=2253, + serialized_start=1983, + serialized_end=2277, ) @@ -1279,8 +1281,8 @@ _SERVICESTATUS = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2255, - serialized_end=2322, + serialized_start=2279, + serialized_end=2346, ) @@ -1311,8 +1313,8 @@ _SERVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2324, - serialized_end=2382, + serialized_start=2348, + serialized_end=2406, ) @@ -1343,8 +1345,8 @@ _SERVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2384, - serialized_end=2440, + serialized_start=2408, + serialized_end=2464, ) @@ -1375,8 +1377,8 @@ _SERVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2442, - serialized_end=2491, + serialized_start=2466, + serialized_end=2515, ) @@ -1414,8 +1416,8 @@ _SERVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2493, - serialized_end=2578, + serialized_start=2517, + serialized_end=2602, ) @@ -1460,8 +1462,8 @@ _ENDPOINTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2581, - serialized_end=2711, + serialized_start=2605, + serialized_end=2735, ) @@ -1499,8 +1501,8 @@ _ENDPOINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2713, - serialized_end=2788, + serialized_start=2737, + serialized_end=2812, ) @@ -1533,6 +1535,13 @@ _CONFIGRULE = _descriptor.Descriptor( 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='kpi_sample_type', full_name='context.ConfigRule.kpi_sample_type', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=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), ], extensions=[ ], @@ -1545,8 +1554,8 @@ _CONFIGRULE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2790, - serialized_end=2891, + serialized_start=2815, + serialized_end=2974, ) @@ -1584,8 +1593,8 @@ _CONSTRAINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2893, - serialized_end=2956, + serialized_start=2976, + serialized_end=3039, ) @@ -1616,8 +1625,8 @@ _CONNECTIONID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2958, - serialized_end=3012, + serialized_start=3041, + serialized_end=3095, ) @@ -1662,8 +1671,8 @@ _CONNECTION = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3015, - serialized_end=3156, + serialized_start=3098, + serialized_end=3239, ) @@ -1694,8 +1703,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3158, - serialized_end=3223, + serialized_start=3241, + serialized_end=3306, ) @@ -1726,8 +1735,8 @@ _CONNECTIONLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3225, - serialized_end=3283, + serialized_start=3308, + serialized_end=3366, ) @@ -1772,8 +1781,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3285, - serialized_end=3379, + serialized_start=3368, + serialized_end=3462, ) @@ -1811,8 +1820,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3381, - serialized_end=3466, + serialized_start=3464, + serialized_end=3549, ) _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM @@ -1871,6 +1880,7 @@ _ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID _ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID _ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID _CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM +_CONFIGRULE.fields_by_name['kpi_sample_type'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID _CONNECTION.fields_by_name['related_service_id'].message_type = _SERVICEID @@ -2224,8 +2234,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=4289, - serialized_end=5990, + serialized_start=4372, + serialized_end=6073, methods=[ _descriptor.MethodDescriptor( name='ListContextIds', diff --git a/src/context/proto/context_pb2_grpc.py b/src/context/proto/context_pb2_grpc.py index c344c8b539324140fddc411324959368da3c1b7b..63a7edb530ab138e7f2d6c2ba2d6075db52e2fee 100644 --- a/src/context/proto/context_pb2_grpc.py +++ b/src/context/proto/context_pb2_grpc.py @@ -6,9 +6,7 @@ from . import context_pb2 as context__pb2 class ContextServiceStub(object): - """import "kpi_sample_types.proto"; - - """ + """Missing associated documentation comment in .proto file.""" def __init__(self, channel): """Constructor. @@ -169,9 +167,7 @@ class ContextServiceStub(object): class ContextServiceServicer(object): - """import "kpi_sample_types.proto"; - - """ + """Missing associated documentation comment in .proto file.""" def ListContextIds(self, request, context): """Missing associated documentation comment in .proto file.""" @@ -514,9 +510,7 @@ def add_ContextServiceServicer_to_server(servicer, server): # This class is part of an EXPERIMENTAL API. class ContextService(object): - """import "kpi_sample_types.proto"; - - """ + """Missing associated documentation comment in .proto file.""" @staticmethod def ListContextIds(request, diff --git a/src/context/proto/kpi_sample_types_pb2.py b/src/context/proto/kpi_sample_types_pb2.py index ad22554ec352d0aeae644fdce00c0f28996ed73b..31fbaa216bca629a4de4272091c490982c1aa166 100644 --- a/src/context/proto/kpi_sample_types_pb2.py +++ b/src/context/proto/kpi_sample_types_pb2.py @@ -2,6 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: kpi_sample_types.proto """Generated protocol buffer code.""" +from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -15,15 +16,62 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='kpi_sample_types.proto', - package='', + package='kpi_sample_types', syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x16kpi_sample_types.protob\x06proto3' + serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*x\n\rKpiSampleType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x17\n\x13PACKETS_TRANSMITTED\x10\x65\x12\x14\n\x10PACKETS_RECEIVED\x10\x66\x12\x16\n\x11\x42YTES_TRANSMITTED\x10\xc9\x01\x12\x13\n\x0e\x42YTES_RECEIVED\x10\xca\x01\x62\x06proto3' ) +_KPISAMPLETYPE = _descriptor.EnumDescriptor( + name='KpiSampleType', + full_name='kpi_sample_types.KpiSampleType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKETS_TRANSMITTED', index=1, number=101, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKETS_RECEIVED', index=2, number=102, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BYTES_TRANSMITTED', index=3, number=201, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BYTES_RECEIVED', index=4, number=202, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=44, + serialized_end=164, +) +_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) + +KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) +UNKNOWN = 0 +PACKETS_TRANSMITTED = 101 +PACKETS_RECEIVED = 102 +BYTES_TRANSMITTED = 201 +BYTES_RECEIVED = 202 +DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py index d97cdb7dfe6594a59be10427ed52341346c19a97..0fe3484896a39545c4dd49042707dc1ee09fc868 100644 --- a/src/context/service/database/ConfigModel.py +++ b/src/context/service/database/ConfigModel.py @@ -1,8 +1,8 @@ import functools, logging, operator from enum import Enum -from typing import Dict, List, Optional, Tuple, Union +from typing import Dict, List, Tuple, Union from common.orm.Database import Database -from common.orm.HighLevel import get_object, get_or_create_object, update_or_create_object +from common.orm.HighLevel import get_or_create_object, update_or_create_object from common.orm.backend.Tools import key_to_str from common.orm.fields.EnumeratedField import EnumeratedField from common.orm.fields.ForeignKeyField import ForeignKeyField @@ -11,7 +11,7 @@ from common.orm.fields.PrimaryKeyField import PrimaryKeyField from common.orm.fields.StringField import StringField from common.orm.model.Model import Model from context.proto.context_pb2 import ConfigActionEnum -from .Tools import fast_hasher, grpc_to_enum, remove_dict_key +from context.service.database.Tools import fast_hasher, grpc_to_enum, remove_dict_key LOGGER = logging.getLogger(__name__) @@ -50,62 +50,35 @@ class ConfigRuleModel(Model): # pylint: disable=abstract-method return result def set_config_rule( - database : Database, db_config : ConfigModel, position : int, resource_key : str, resource_value : str + database : Database, db_config : ConfigModel, grpc_config_rule, position : int ) -> Tuple[ConfigRuleModel, bool]: - str_rule_key_hash = fast_hasher(resource_key) + str_rule_key_hash = fast_hasher(grpc_config_rule.resource_key) str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') + result : Tuple[ConfigRuleModel, bool] = update_or_create_object(database, ConfigRuleModel, str_config_rule_key, { - 'config_fk': db_config, 'position': position, 'action': ORM_ConfigActionEnum.SET, - 'key': resource_key, 'value': resource_value}) + 'config_fk': db_config, + 'position' : position, + 'action' : grpc_to_enum__config_action(grpc_config_rule.action), + 'key' : grpc_config_rule.resource_key, + 'value' : grpc_config_rule.resource_value, + }) db_config_rule, updated = result return db_config_rule, updated -def delete_config_rule( - database : Database, db_config : ConfigModel, resource_key : str - ) -> None: - - str_rule_key_hash = fast_hasher(resource_key) - str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') - db_config_rule : Optional[ConfigRuleModel] = get_object( - database, ConfigRuleModel, str_config_rule_key, raise_if_not_found=False) - if db_config_rule is None: return - db_config_rule.delete() - -def delete_all_config_rules( - database : Database, db_config : ConfigModel - ) -> None: - - db_config_rule_pks = db_config.references(ConfigRuleModel) - for pk,_ in db_config_rule_pks: ConfigRuleModel(database, pk).delete() - -def grpc_config_rules_to_raw(grpc_config_rules) -> List[Tuple[ORM_ConfigActionEnum, str, str]]: - def translate(grpc_config_rule): - action = grpc_to_enum__config_action(grpc_config_rule.action) - return action, grpc_config_rule.resource_key, grpc_config_rule.resource_value - return [translate(grpc_config_rule) for grpc_config_rule in grpc_config_rules] - -def update_config( - database : Database, db_parent_pk : str, config_name : str, - raw_config_rules : List[Tuple[ORM_ConfigActionEnum, str, str]] +def set_config( + database : Database, db_parent_pk : str, config_name : str, grpc_config_rules ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]: str_config_key = key_to_str([db_parent_pk, config_name], separator=':') result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key) db_config, created = result - db_objects : List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]] = [(db_config, created)] + db_objects = [(db_config, created)] - for position,(action, resource_key, resource_value) in enumerate(raw_config_rules): - if action == ORM_ConfigActionEnum.SET: - result : Tuple[ConfigRuleModel, bool] = set_config_rule( - database, db_config, position, resource_key, resource_value) - db_config_rule, updated = result - db_objects.append((db_config_rule, updated)) - elif action == ORM_ConfigActionEnum.DELETE: - delete_config_rule(database, db_config, resource_key) - else: - msg = 'Unsupported action({:s}) for resource_key({:s})/resource_value({:s})' - raise AttributeError(msg.format(str(ConfigActionEnum.Name(action)), str(resource_key), str(resource_value))) + for position,grpc_config_rule in enumerate(grpc_config_rules): + result : Tuple[ConfigRuleModel, bool] = set_config_rule(database, db_config, grpc_config_rule, position) + db_config_rule, updated = result + db_objects.append((db_config_rule, updated)) return db_objects diff --git a/src/context/service/database/EndPointModel.py b/src/context/service/database/EndPointModel.py index 38b87d6f37c4e99dd3790f4d8802acd03873f77d..b7c220a00b2a85b2c3f4c11a2eceb3aa66aadc5a 100644 --- a/src/context/service/database/EndPointModel.py +++ b/src/context/service/database/EndPointModel.py @@ -4,8 +4,8 @@ from common.orm.fields.ForeignKeyField import ForeignKeyField from common.orm.fields.PrimaryKeyField import PrimaryKeyField from common.orm.fields.StringField import StringField from common.orm.model.Model import Model -from .DeviceModel import DeviceModel -from .TopologyModel import TopologyModel +from context.service.database.DeviceModel import DeviceModel +from context.service.database.TopologyModel import TopologyModel LOGGER = logging.getLogger(__name__) diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py index e76c399cd4e17578a01ac7bf88cb0fc3f7017b8e..d8f7b648b4b919cc61330f236195c444f550ede1 100644 --- a/src/context/service/grpc_server/ContextServiceServicerImpl.py +++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py @@ -12,7 +12,7 @@ from context.proto.context_pb2 import ( DeviceList, Empty, EventTypeEnum, Link, LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList) from context.proto.context_pb2_grpc import ContextServiceServicer -from context.service.database.ConfigModel import ConfigModel, ConfigRuleModel, grpc_config_rules_to_raw, update_config +from context.service.database.ConfigModel import ConfigModel, ConfigRuleModel, set_config from context.service.database.ConstraintModel import ConstraintModel, ConstraintsModel, set_constraints from context.service.database.ContextModel import ContextModel from context.service.database.DeviceModel import ( @@ -236,8 +236,7 @@ class ContextServiceServicerImpl(ContextServiceServicer): 'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid, ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)]) - config_rules = grpc_config_rules_to_raw(request.device_config.config_rules) - running_config_result = update_config(self.database, device_uuid, 'running', config_rules) + running_config_result = set_config(self.database, device_uuid, 'running', request.device_config.config_rules) db_running_config = running_config_result[0][0] result : Tuple[DeviceModel, bool] = update_or_create_object(self.database, DeviceModel, device_uuid, { @@ -453,8 +452,8 @@ class ContextServiceServicerImpl(ContextServiceServicer): self.database, str_service_key, 'constraints', request.service_constraints) db_constraints = constraints_result[0][0] - config_rules = grpc_config_rules_to_raw(request.service_config.config_rules) - running_config_result = update_config(self.database, str_service_key, 'running', config_rules) + running_config_result = set_config( + self.database, str_service_key, 'running', request.service_config.config_rules) db_running_config = running_config_result[0][0] result : Tuple[ServiceModel, bool] = update_or_create_object(self.database, ServiceModel, str_service_key, { diff --git a/src/context/tests/example_objects.py b/src/context/tests/example_objects.py index 81339c04e1fe77667bd41179f3fa0813c5fc69df..226119f9d29213a6f1857a476b37b32c9941a813 100644 --- a/src/context/tests/example_objects.py +++ b/src/context/tests/example_objects.py @@ -2,12 +2,13 @@ from copy import deepcopy from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID from context.proto.context_pb2 import ( ConfigActionEnum, DeviceDriverEnum, DeviceOperationalStatusEnum, ServiceStatusEnum, ServiceTypeEnum) +from context.proto.kpi_sample_types_pb2 import KpiSampleType # Some example objects to be used by the tests # Helper methods -def config_rule(action, resource_key, resource_value): - return {'action': action, 'resource_key': resource_key, 'resource_value': resource_value} +def config_rule(action, resource_key, resource_value, kpi_sample_type): + return {'action': action, 'resource_key': resource_key, 'resource_value': resource_value, 'kpi_sample_type': kpi_sample_type} def endpoint_id(topology_id, device_id, endpoint_uuid): return {'topology_id': deepcopy(topology_id), 'device_id': deepcopy(device_id), @@ -40,9 +41,10 @@ DEVICE1 = { 'device_id': deepcopy(DEVICE1_ID), 'device_type': 'packet-router', 'device_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value1'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value2'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value3'), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value1', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value2', KpiSampleType.PACKETS_RECEIVED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value3', KpiSampleType.BYTES_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc4/value', 'value4', KpiSampleType.BYTES_RECEIVED), ]}, 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, 'device_drivers': [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_P4], @@ -59,9 +61,9 @@ DEVICE2 = { 'device_id': deepcopy(DEVICE2_ID), 'device_type': 'packet-router', 'device_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value4'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value5'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value6'), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value4', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value5', KpiSampleType.PACKETS_RECEIVED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value6', KpiSampleType.BYTES_TRANSMITTED), ]}, 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, 'device_drivers': [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_P4], @@ -78,9 +80,9 @@ DEVICE3 = { 'device_id': deepcopy(DEVICE3_ID), 'device_type': 'packet-router', 'device_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value4'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value5'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value6'), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc1/value', 'value4', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc2/value', 'value5', KpiSampleType.PACKETS_RECEIVED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'dev/rsrc3/value', 'value6', KpiSampleType.BYTES_TRANSMITTED), ]}, 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED, 'device_drivers': [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG, DeviceDriverEnum.DEVICEDRIVER_P4], @@ -139,9 +141,9 @@ SERVICE_DEV1_DEV2 = { ], 'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_ACTIVE}, 'service_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9'), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9', KpiSampleType.PACKETS_TRANSMITTED), ]}, } @@ -163,9 +165,9 @@ SERVICE_DEV1_DEV3 = { ], 'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_ACTIVE}, 'service_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9'), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9', KpiSampleType.PACKETS_TRANSMITTED), ]}, } @@ -187,8 +189,8 @@ SERVICE_DEV2_DEV3 = { ], 'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_ACTIVE}, 'service_config': {'config_rules': [ - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8'), - config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9'), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc1/value', 'value7', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc2/value', 'value8', KpiSampleType.PACKETS_TRANSMITTED), + config_rule(ConfigActionEnum.CONFIGACTION_SET, 'svc/rsrc3/value', 'value9', KpiSampleType.PACKETS_TRANSMITTED), ]}, } diff --git a/src/device/.gitlab-ci.yml b/src/device/.gitlab-ci.yml index e6ee81e379f8eeeca6c715bff5dfc6f2cf1c3d23..fca94bf712606f590c13c3e90f8fc686b9238471 100644 --- a/src/device/.gitlab-ci.yml +++ b/src/device/.gitlab-ci.yml @@ -35,7 +35,7 @@ unit_test device: - sleep 5 - docker ps -a - docker logs $IMAGE_NAME - - docker exec -i $IMAGE_NAME bash -c "pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary_driverapi.py $IMAGE_NAME/tests/test_unitary.py" + - docker exec -i $IMAGE_NAME bash -c "pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary_service.py $IMAGE_NAME/tests/test_unitary_driverapi.py" after_script: - docker stop $IMAGE_NAME - docker rm $IMAGE_NAME diff --git a/src/device/Config.py b/src/device/Config.py index 753f4b57b2767552317882e72622c613f40e3ea2..6787413a881b4d84ed6b4ecb5e041901399a4ae6 100644 --- a/src/device/Config.py +++ b/src/device/Config.py @@ -10,9 +10,3 @@ GRPC_GRACE_PERIOD = 60 # Prometheus settings METRICS_PORT = 9192 - -# Dependency micro-service connection settings -CONTEXT_SERVICE_HOST = '127.0.0.1' -CONTEXT_SERVICE_PORT = 1010 -MONITORING_SERVICE_HOST = '127.0.0.1' -MONITORING_SERVICE_PORT = 7070 diff --git a/src/device/Dockerfile b/src/device/Dockerfile index 70e3c8dcbbc6b78a53b468e51034ffb8e69f8e53..52eb5c82cce99ebc488ae586fd29375dba709a09 100644 --- a/src/device/Dockerfile +++ b/src/device/Dockerfile @@ -29,9 +29,7 @@ RUN python3 -m pip install -r device/requirements.in # Add files into working directory COPY common/. common -COPY context/. context COPY device/. device -COPY monitoring/. monitoring # Start device service ENTRYPOINT ["python", "-m", "device.service"] diff --git a/src/device/client/DeviceClient.py b/src/device/client/DeviceClient.py index 3841bf8cb4892dcc191d536061aea2bb1bd9d06d..d9cd16f77b607ac0817c16448d65c7f563201646 100644 --- a/src/device/client/DeviceClient.py +++ b/src/device/client/DeviceClient.py @@ -1,7 +1,7 @@ import grpc, logging from common.tools.client.RetryDecorator import retry, delay_exponential -from device.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty -#from device.proto.device_pb2 import MonitoringSettings +from device.proto.context_pb2 import Device, DeviceId, Empty +from device.proto.device_pb2 import MonitoringSettings from device.proto.device_pb2_grpc import DeviceServiceStub LOGGER = logging.getLogger(__name__) @@ -22,7 +22,7 @@ class DeviceClient: self.stub = DeviceServiceStub(self.channel) def close(self): - if self.channel is not None: self.channel.close() + if(self.channel is not None): self.channel.close() self.channel = None self.stub = None @@ -48,15 +48,8 @@ class DeviceClient: return response @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') - def GetInitialConfig(self, request : DeviceId) -> DeviceConfig: - LOGGER.debug('GetInitialConfig request: {:s}'.format(str(request))) - response = self.stub.GetInitialConfig(request) - LOGGER.debug('GetInitialConfig result: {:s}'.format(str(response))) + def MonitorDeviceKpi(self, request: MonitoringSettings) -> Empty: + LOGGER.debug('MonitorDeviceKpi request: {:s}'.format(str(request))) + response = self.stub.MonitorDeviceKpi(request) + LOGGER.debug('MonitorDeviceKpi result: {:s}'.format(str(response))) return response - - #@retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') - #def MonitorDeviceKpi(self, request : MonitoringSettings) -> Empty: - # LOGGER.debug('MonitorDeviceKpi request: {:s}'.format(str(request))) - # response = self.stub.MonitorDeviceKpi(request) - # LOGGER.debug('MonitorDeviceKpi result: {:s}'.format(str(response))) - # return response diff --git a/src/device/genproto.sh b/src/device/genproto.sh index 31632fb894f3ede9582063d81b1911fe2551d96d..c5f9ec20f289ff2005641ac2489db1469fcbcaaf 100755 --- a/src/device/genproto.sh +++ b/src/device/genproto.sh @@ -26,14 +26,10 @@ touch proto/__init__.py python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto device.proto python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto -python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto monitoring.proto rm proto/context_pb2_grpc.py rm proto/kpi_sample_types_pb2_grpc.py -rm proto/monitoring_pb2_grpc.py sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/device_pb2.py sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/device_pb2_grpc.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py -sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/monitoring_pb2.py diff --git a/src/device/proto/context_pb2.py b/src/device/proto/context_pb2.py index 8b4848bc33bfb0eba76590c8a3a627b2db84ca9f..658c58897615b33a435c7004d05b0a291abf95b7 100644 --- a/src/device/proto/context_pb2.py +++ b/src/device/proto/context_pb2.py @@ -12,6 +12,7 @@ from google.protobuf import symbol_database as _symbol_database _sym_db = _symbol_database.Default() +from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -20,8 +21,9 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"K\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' -) + serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"K\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\"\x9f\x01\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\x12\x38\n\x0fkpi_sample_type\x18\x04 \x01(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' + , + dependencies=[kpi__sample__types__pb2.DESCRIPTOR,]) _EVENTTYPEENUM = _descriptor.EnumDescriptor( name='EventTypeEnum', @@ -53,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3468, - serialized_end=3574, + serialized_start=3551, + serialized_end=3657, ) _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM) @@ -99,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3577, - serialized_end=3774, + serialized_start=3660, + serialized_end=3857, ) _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM) @@ -130,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3777, - serialized_end=3920, + serialized_start=3860, + serialized_end=4003, ) _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM) @@ -166,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3923, - serialized_end=4052, + serialized_start=4006, + serialized_end=4135, ) _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM) @@ -202,8 +204,8 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4055, - serialized_end=4191, + serialized_start=4138, + serialized_end=4274, ) _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM) @@ -233,8 +235,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4193, - serialized_end=4286, + serialized_start=4276, + serialized_end=4369, ) _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM) @@ -286,8 +288,8 @@ _EMPTY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=26, - serialized_end=33, + serialized_start=50, + serialized_end=57, ) @@ -318,8 +320,8 @@ _UUID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=35, - serialized_end=55, + serialized_start=59, + serialized_end=79, ) @@ -357,8 +359,8 @@ _EVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=57, - serialized_end=127, + serialized_start=81, + serialized_end=151, ) @@ -389,8 +391,8 @@ _CONTEXTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=129, - serialized_end=177, + serialized_start=153, + serialized_end=201, ) @@ -442,8 +444,8 @@ _CONTEXT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=180, - serialized_end=362, + serialized_start=204, + serialized_end=386, ) @@ -474,8 +476,8 @@ _CONTEXTIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=364, - serialized_end=420, + serialized_start=388, + serialized_end=444, ) @@ -506,8 +508,8 @@ _CONTEXTLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=422, - serialized_end=471, + serialized_start=446, + serialized_end=495, ) @@ -545,8 +547,8 @@ _CONTEXTEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=473, - serialized_end=558, + serialized_start=497, + serialized_end=582, ) @@ -584,8 +586,8 @@ _TOPOLOGYID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=560, - serialized_end=650, + serialized_start=584, + serialized_end=674, ) @@ -630,8 +632,8 @@ _TOPOLOGY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=652, - serialized_end=778, + serialized_start=676, + serialized_end=802, ) @@ -662,8 +664,8 @@ _TOPOLOGYIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=780, - serialized_end=839, + serialized_start=804, + serialized_end=863, ) @@ -694,8 +696,8 @@ _TOPOLOGYLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=841, - serialized_end=894, + serialized_start=865, + serialized_end=918, ) @@ -733,8 +735,8 @@ _TOPOLOGYEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=896, - serialized_end=984, + serialized_start=920, + serialized_end=1008, ) @@ -765,8 +767,8 @@ _DEVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=986, - serialized_end=1032, + serialized_start=1010, + serialized_end=1056, ) @@ -832,8 +834,8 @@ _DEVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1035, - serialized_end=1317, + serialized_start=1059, + serialized_end=1341, ) @@ -864,8 +866,8 @@ _DEVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1319, - serialized_end=1376, + serialized_start=1343, + serialized_end=1400, ) @@ -896,8 +898,8 @@ _DEVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1378, - serialized_end=1431, + serialized_start=1402, + serialized_end=1455, ) @@ -928,8 +930,8 @@ _DEVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1433, - serialized_end=1479, + serialized_start=1457, + serialized_end=1503, ) @@ -967,8 +969,8 @@ _DEVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1481, - serialized_end=1563, + serialized_start=1505, + serialized_end=1587, ) @@ -999,8 +1001,8 @@ _LINKID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1565, - serialized_end=1607, + serialized_start=1589, + serialized_end=1631, ) @@ -1038,8 +1040,8 @@ _LINK = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1609, - serialized_end=1697, + serialized_start=1633, + serialized_end=1721, ) @@ -1070,8 +1072,8 @@ _LINKIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1699, - serialized_end=1746, + serialized_start=1723, + serialized_end=1770, ) @@ -1102,8 +1104,8 @@ _LINKLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1748, - serialized_end=1788, + serialized_start=1772, + serialized_end=1812, ) @@ -1141,8 +1143,8 @@ _LINKEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1790, - serialized_end=1866, + serialized_start=1814, + serialized_end=1890, ) @@ -1180,8 +1182,8 @@ _SERVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1868, - serialized_end=1956, + serialized_start=1892, + serialized_end=1980, ) @@ -1247,8 +1249,8 @@ _SERVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1959, - serialized_end=2253, + serialized_start=1983, + serialized_end=2277, ) @@ -1279,8 +1281,8 @@ _SERVICESTATUS = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2255, - serialized_end=2322, + serialized_start=2279, + serialized_end=2346, ) @@ -1311,8 +1313,8 @@ _SERVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2324, - serialized_end=2382, + serialized_start=2348, + serialized_end=2406, ) @@ -1343,8 +1345,8 @@ _SERVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2384, - serialized_end=2440, + serialized_start=2408, + serialized_end=2464, ) @@ -1375,8 +1377,8 @@ _SERVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2442, - serialized_end=2491, + serialized_start=2466, + serialized_end=2515, ) @@ -1414,8 +1416,8 @@ _SERVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2493, - serialized_end=2578, + serialized_start=2517, + serialized_end=2602, ) @@ -1460,8 +1462,8 @@ _ENDPOINTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2581, - serialized_end=2711, + serialized_start=2605, + serialized_end=2735, ) @@ -1499,8 +1501,8 @@ _ENDPOINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2713, - serialized_end=2788, + serialized_start=2737, + serialized_end=2812, ) @@ -1533,6 +1535,13 @@ _CONFIGRULE = _descriptor.Descriptor( 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='kpi_sample_type', full_name='context.ConfigRule.kpi_sample_type', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=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), ], extensions=[ ], @@ -1545,8 +1554,8 @@ _CONFIGRULE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2790, - serialized_end=2891, + serialized_start=2815, + serialized_end=2974, ) @@ -1584,8 +1593,8 @@ _CONSTRAINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2893, - serialized_end=2956, + serialized_start=2976, + serialized_end=3039, ) @@ -1616,8 +1625,8 @@ _CONNECTIONID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2958, - serialized_end=3012, + serialized_start=3041, + serialized_end=3095, ) @@ -1662,8 +1671,8 @@ _CONNECTION = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3015, - serialized_end=3156, + serialized_start=3098, + serialized_end=3239, ) @@ -1694,8 +1703,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3158, - serialized_end=3223, + serialized_start=3241, + serialized_end=3306, ) @@ -1726,8 +1735,8 @@ _CONNECTIONLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3225, - serialized_end=3283, + serialized_start=3308, + serialized_end=3366, ) @@ -1772,8 +1781,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3285, - serialized_end=3379, + serialized_start=3368, + serialized_end=3462, ) @@ -1811,8 +1820,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3381, - serialized_end=3466, + serialized_start=3464, + serialized_end=3549, ) _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM @@ -1871,6 +1880,7 @@ _ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID _ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID _ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID _CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM +_CONFIGRULE.fields_by_name['kpi_sample_type'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID _CONNECTION.fields_by_name['related_service_id'].message_type = _SERVICEID @@ -2224,8 +2234,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=4289, - serialized_end=5990, + serialized_start=4372, + serialized_end=6073, methods=[ _descriptor.MethodDescriptor( name='ListContextIds', diff --git a/src/device/proto/device_pb2.py b/src/device/proto/device_pb2.py index e351738e6ac1ea9dadf4310897a979ab38db669b..4d4dbb82567256dd79595884f0ed9c2f13498d31 100644 --- a/src/device/proto/device_pb2.py +++ b/src/device/proto/device_pb2.py @@ -12,6 +12,7 @@ _sym_db = _symbol_database.Default() from . import context_pb2 as context__pb2 +from . import monitoring_pb2 as monitoring__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -20,14 +21,77 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x0c\x64\x65vice.proto\x12\x06\x64\x65vice\x1a\rcontext.proto2\xf0\x01\n\rDeviceService\x12\x31\n\tAddDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x37\n\x0f\x43onfigureDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0c\x44\x65leteDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12>\n\x10GetInitialConfig\x12\x11.context.DeviceId\x1a\x15.context.DeviceConfig\"\x00\x62\x06proto3' + serialized_pb=b'\n\x0c\x64\x65vice.proto\x12\x06\x64\x65vice\x1a\rcontext.proto\x1a\x10monitoring.proto\"\xa4\x01\n\x12MonitoringSettings\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x31\n\x0ekpi_descriptor\x18\x02 \x01(\x0b\x32\x19.monitoring.KpiDescriptor\x12\x1b\n\x13sampling_duration_s\x18\x03 \x01(\x02\x12\x1b\n\x13sampling_interval_s\x18\x04 \x01(\x02\x32\xb2\x02\n\rDeviceService\x12\x31\n\tAddDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x37\n\x0f\x43onfigureDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0c\x44\x65leteDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12>\n\x10GetInitialConfig\x12\x11.context.DeviceId\x1a\x15.context.DeviceConfig\"\x00\x12@\n\x10MonitorDeviceKpi\x12\x1a.device.MonitoringSettings\x1a\x0e.context.Empty\"\x00\x62\x06proto3' , - dependencies=[context__pb2.DESCRIPTOR,]) + dependencies=[context__pb2.DESCRIPTOR,monitoring__pb2.DESCRIPTOR,]) + +_MONITORINGSETTINGS = _descriptor.Descriptor( + name='MonitoringSettings', + full_name='device.MonitoringSettings', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='kpi_id', full_name='device.MonitoringSettings.kpi_id', 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, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='kpi_descriptor', full_name='device.MonitoringSettings.kpi_descriptor', index=1, + number=2, 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, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sampling_duration_s', full_name='device.MonitoringSettings.sampling_duration_s', index=2, + number=3, 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='sampling_interval_s', full_name='device.MonitoringSettings.sampling_interval_s', 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), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=58, + serialized_end=222, +) + +_MONITORINGSETTINGS.fields_by_name['kpi_id'].message_type = monitoring__pb2._KPIID +_MONITORINGSETTINGS.fields_by_name['kpi_descriptor'].message_type = monitoring__pb2._KPIDESCRIPTOR +DESCRIPTOR.message_types_by_name['MonitoringSettings'] = _MONITORINGSETTINGS _sym_db.RegisterFileDescriptor(DESCRIPTOR) +MonitoringSettings = _reflection.GeneratedProtocolMessageType('MonitoringSettings', (_message.Message,), { + 'DESCRIPTOR' : _MONITORINGSETTINGS, + '__module__' : 'device_pb2' + # @@protoc_insertion_point(class_scope:device.MonitoringSettings) + }) +_sym_db.RegisterMessage(MonitoringSettings) + _DEVICESERVICE = _descriptor.ServiceDescriptor( @@ -37,8 +101,8 @@ _DEVICESERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=40, - serialized_end=280, + serialized_start=225, + serialized_end=531, methods=[ _descriptor.MethodDescriptor( name='AddDevice', @@ -80,6 +144,16 @@ _DEVICESERVICE = _descriptor.ServiceDescriptor( serialized_options=None, create_key=_descriptor._internal_create_key, ), + _descriptor.MethodDescriptor( + name='MonitorDeviceKpi', + full_name='device.DeviceService.MonitorDeviceKpi', + index=4, + containing_service=None, + input_type=_MONITORINGSETTINGS, + output_type=context__pb2._EMPTY, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), ]) _sym_db.RegisterServiceDescriptor(_DEVICESERVICE) diff --git a/src/device/proto/device_pb2_grpc.py b/src/device/proto/device_pb2_grpc.py index 453aa2fcbc9296cf25298c2041433dfbb06b8e28..2b9bfc47da3b33b632ff46a8454496a499305a6c 100644 --- a/src/device/proto/device_pb2_grpc.py +++ b/src/device/proto/device_pb2_grpc.py @@ -3,6 +3,7 @@ import grpc from . import context_pb2 as context__pb2 +from . import device_pb2 as device__pb2 class DeviceServiceStub(object): @@ -34,6 +35,11 @@ class DeviceServiceStub(object): request_serializer=context__pb2.DeviceId.SerializeToString, response_deserializer=context__pb2.DeviceConfig.FromString, ) + self.MonitorDeviceKpi = channel.unary_unary( + '/device.DeviceService/MonitorDeviceKpi', + request_serializer=device__pb2.MonitoringSettings.SerializeToString, + response_deserializer=context__pb2.Empty.FromString, + ) class DeviceServiceServicer(object): @@ -63,6 +69,12 @@ class DeviceServiceServicer(object): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def MonitorDeviceKpi(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 add_DeviceServiceServicer_to_server(servicer, server): rpc_method_handlers = { @@ -86,6 +98,11 @@ def add_DeviceServiceServicer_to_server(servicer, server): request_deserializer=context__pb2.DeviceId.FromString, response_serializer=context__pb2.DeviceConfig.SerializeToString, ), + 'MonitorDeviceKpi': grpc.unary_unary_rpc_method_handler( + servicer.MonitorDeviceKpi, + request_deserializer=device__pb2.MonitoringSettings.FromString, + response_serializer=context__pb2.Empty.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'device.DeviceService', rpc_method_handlers) @@ -163,3 +180,20 @@ class DeviceService(object): context__pb2.DeviceConfig.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def MonitorDeviceKpi(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, '/device.DeviceService/MonitorDeviceKpi', + device__pb2.MonitoringSettings.SerializeToString, + context__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/device/proto/kpi_sample_types_pb2.py b/src/device/proto/kpi_sample_types_pb2.py index ad22554ec352d0aeae644fdce00c0f28996ed73b..31fbaa216bca629a4de4272091c490982c1aa166 100644 --- a/src/device/proto/kpi_sample_types_pb2.py +++ b/src/device/proto/kpi_sample_types_pb2.py @@ -2,6 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: kpi_sample_types.proto """Generated protocol buffer code.""" +from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -15,15 +16,62 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='kpi_sample_types.proto', - package='', + package='kpi_sample_types', syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x16kpi_sample_types.protob\x06proto3' + serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*x\n\rKpiSampleType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x17\n\x13PACKETS_TRANSMITTED\x10\x65\x12\x14\n\x10PACKETS_RECEIVED\x10\x66\x12\x16\n\x11\x42YTES_TRANSMITTED\x10\xc9\x01\x12\x13\n\x0e\x42YTES_RECEIVED\x10\xca\x01\x62\x06proto3' ) +_KPISAMPLETYPE = _descriptor.EnumDescriptor( + name='KpiSampleType', + full_name='kpi_sample_types.KpiSampleType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKETS_TRANSMITTED', index=1, number=101, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKETS_RECEIVED', index=2, number=102, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BYTES_TRANSMITTED', index=3, number=201, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BYTES_RECEIVED', index=4, number=202, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=44, + serialized_end=164, +) +_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) + +KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) +UNKNOWN = 0 +PACKETS_TRANSMITTED = 101 +PACKETS_RECEIVED = 102 +BYTES_TRANSMITTED = 201 +BYTES_RECEIVED = 202 +DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) diff --git a/src/device/proto/monitoring_pb2.py b/src/device/proto/monitoring_pb2.py index 7368609d2145f94cc3b746836a5297333151c738..b313ebb68f0da37a540898e8c362fd204a799076 100644 --- a/src/device/proto/monitoring_pb2.py +++ b/src/device/proto/monitoring_pb2.py @@ -2,7 +2,6 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: monitoring.proto """Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -13,6 +12,7 @@ _sym_db = _symbol_database.Default() from . import context_pb2 as context__pb2 +from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -21,177 +21,53 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x10monitoring.proto\x12\nmonitoring\x1a\rcontext.proto\"\x84\x01\n\x10\x43reateKpiRequest\x12\x16\n\x0ekpiDescription\x18\x01 \x01(\t\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12\x32\n\x0fkpi_sample_type\x18\x03 \x01(\x0e\x32\x19.monitoring.KpiSampleType\"h\n\x11MonitorKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x18\n\x10\x63onnexion_time_s\x18\x02 \x01(\r\x12\x16\n\x0esample_rate_ms\x18\x03 \x01(\r\"i\n\x17MonitorDeviceKpiRequest\x12\x1c\n\x03kpi\x18\x01 \x01(\x0b\x32\x0f.monitoring.Kpi\x12\x18\n\x10\x63onnexion_time_s\x18\x02 \x01(\r\x12\x16\n\x0esample_rate_ms\x18\x03 \x01(\r\"s\n\x11IncludeKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x12\n\ntime_stamp\x18\x02 \x01(\t\x12\'\n\tkpi_value\x18\x03 \x01(\x0b\x32\x14.monitoring.KpiValue\"&\n\x05KpiId\x12\x1d\n\x06kpi_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xd6\x01\n\x03Kpi\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x16\n\x0ekpiDescription\x18\x03 \x01(\t\x12\'\n\tkpi_value\x18\x04 \x01(\x0b\x32\x14.monitoring.KpiValue\x12\x32\n\x0fkpi_sample_type\x18\x05 \x01(\x0e\x32\x19.monitoring.KpiSampleType\x12$\n\tdevice_id\x18\x06 \x01(\x0b\x32\x11.context.DeviceId\"a\n\x08KpiValue\x12\x10\n\x06intVal\x18\x01 \x01(\rH\x00\x12\x12\n\x08\x66loatVal\x18\x02 \x01(\x02H\x00\x12\x13\n\tstringVal\x18\x03 \x01(\tH\x00\x12\x11\n\x07\x62oolVal\x18\x04 \x01(\x08H\x00\x42\x07\n\x05value\"+\n\x07KpiList\x12 \n\x07kpiList\x18\x01 \x03(\x0b\x32\x0f.monitoring.Kpi*x\n\rKpiSampleType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x17\n\x13PACKETS_TRANSMITTED\x10\x65\x12\x14\n\x10PACKETS_RECEIVED\x10\x66\x12\x16\n\x11\x42YTES_TRANSMITTED\x10\xc9\x01\x12\x13\n\x0e\x42YTES_RECEIVED\x10\xca\x01\x32\x8b\x03\n\x11MonitoringService\x12>\n\tCreateKpi\x12\x1c.monitoring.CreateKpiRequest\x1a\x11.monitoring.KpiId\"\x00\x12=\n\nIncludeKpi\x12\x1d.monitoring.IncludeKpiRequest\x1a\x0e.context.Empty\"\x00\x12=\n\nMonitorKpi\x12\x1d.monitoring.MonitorKpiRequest\x1a\x0e.context.Empty\"\x00\x12I\n\x10MonitorDeviceKpi\x12#.monitoring.MonitorDeviceKpiRequest\x1a\x0e.context.Empty\"\x00\x12\x36\n\x0cGetStreamKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x30\x01\x12\x35\n\rGetInstantKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x62\x06proto3' + serialized_pb=b'\n\x10monitoring.proto\x12\nmonitoring\x1a\rcontext.proto\x1a\x16kpi_sample_types.proto\"\xda\x01\n\rKpiDescriptor\x12\x17\n\x0fkpi_description\x18\x01 \x01(\t\x12\x38\n\x0fkpi_sample_type\x18\x02 \x01(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\x12$\n\tdevice_id\x18\x03 \x01(\x0b\x32\x11.context.DeviceId\x12(\n\x0b\x65ndpoint_id\x18\x04 \x01(\x0b\x32\x13.context.EndPointId\x12&\n\nservice_id\x18\x05 \x01(\x0b\x32\x12.context.ServiceId\"p\n\x11MonitorKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x1b\n\x13sampling_duration_s\x18\x02 \x01(\x02\x12\x1b\n\x13sampling_interval_s\x18\x03 \x01(\x02\"&\n\x05KpiId\x12\x1d\n\x06kpi_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"d\n\x03Kpi\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\'\n\tkpi_value\x18\x04 \x01(\x0b\x32\x14.monitoring.KpiValue\"a\n\x08KpiValue\x12\x10\n\x06intVal\x18\x01 \x01(\rH\x00\x12\x12\n\x08\x66loatVal\x18\x02 \x01(\x02H\x00\x12\x13\n\tstringVal\x18\x03 \x01(\tH\x00\x12\x11\n\x07\x62oolVal\x18\x04 \x01(\x08H\x00\x42\x07\n\x05value\",\n\x07KpiList\x12!\n\x08kpi_list\x18\x01 \x03(\x0b\x32\x0f.monitoring.Kpi2\xf3\x02\n\x11MonitoringService\x12;\n\tCreateKpi\x12\x19.monitoring.KpiDescriptor\x1a\x11.monitoring.KpiId\"\x00\x12\x42\n\x10GetKpiDescriptor\x12\x11.monitoring.KpiId\x1a\x19.monitoring.KpiDescriptor\"\x00\x12/\n\nIncludeKpi\x12\x0f.monitoring.Kpi\x1a\x0e.context.Empty\"\x00\x12=\n\nMonitorKpi\x12\x1d.monitoring.MonitorKpiRequest\x1a\x0e.context.Empty\"\x00\x12\x36\n\x0cGetStreamKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x30\x01\x12\x35\n\rGetInstantKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x62\x06proto3' , - dependencies=[context__pb2.DESCRIPTOR,]) + dependencies=[context__pb2.DESCRIPTOR,kpi__sample__types__pb2.DESCRIPTOR,]) -_KPISAMPLETYPE = _descriptor.EnumDescriptor( - name='KpiSampleType', - full_name='monitoring.KpiSampleType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='PACKETS_TRANSMITTED', index=1, number=101, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='PACKETS_RECEIVED', index=2, number=102, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='BYTES_TRANSMITTED', index=3, number=201, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='BYTES_RECEIVED', index=4, number=202, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=913, - serialized_end=1033, -) -_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) - -KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) -UNKNOWN = 0 -PACKETS_TRANSMITTED = 101 -PACKETS_RECEIVED = 102 -BYTES_TRANSMITTED = 201 -BYTES_RECEIVED = 202 -_CREATEKPIREQUEST = _descriptor.Descriptor( - name='CreateKpiRequest', - full_name='monitoring.CreateKpiRequest', +_KPIDESCRIPTOR = _descriptor.Descriptor( + name='KpiDescriptor', + full_name='monitoring.KpiDescriptor', filename=None, file=DESCRIPTOR, containing_type=None, create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='kpiDescription', full_name='monitoring.CreateKpiRequest.kpiDescription', index=0, + name='kpi_description', full_name='monitoring.KpiDescriptor.kpi_description', 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='device_id', full_name='monitoring.CreateKpiRequest.device_id', index=1, - number=2, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_type', full_name='monitoring.CreateKpiRequest.kpi_sample_type', index=2, - number=3, type=14, cpp_type=8, label=1, + name='kpi_sample_type', full_name='monitoring.KpiDescriptor.kpi_sample_type', index=1, + number=2, type=14, cpp_type=8, label=1, has_default_value=False, default_value=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), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=48, - serialized_end=180, -) - - -_MONITORKPIREQUEST = _descriptor.Descriptor( - name='MonitorKpiRequest', - full_name='monitoring.MonitorKpiRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.MonitorKpiRequest.kpi_id', index=0, - number=1, type=11, cpp_type=10, label=1, + name='device_id', full_name='monitoring.KpiDescriptor.device_id', index=2, + number=3, 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='connexion_time_s', full_name='monitoring.MonitorKpiRequest.connexion_time_s', index=1, - number=2, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sample_rate_ms', full_name='monitoring.MonitorKpiRequest.sample_rate_ms', index=2, - number=3, 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, - 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=182, - serialized_end=286, -) - - -_MONITORDEVICEKPIREQUEST = _descriptor.Descriptor( - name='MonitorDeviceKpiRequest', - full_name='monitoring.MonitorDeviceKpiRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi', full_name='monitoring.MonitorDeviceKpiRequest.kpi', index=0, - number=1, type=11, cpp_type=10, label=1, + name='endpoint_id', full_name='monitoring.KpiDescriptor.endpoint_id', index=3, + number=4, 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='connexion_time_s', full_name='monitoring.MonitorDeviceKpiRequest.connexion_time_s', index=1, - number=2, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sample_rate_ms', full_name='monitoring.MonitorDeviceKpiRequest.sample_rate_ms', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, + name='service_id', full_name='monitoring.KpiDescriptor.service_id', 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), @@ -207,37 +83,37 @@ _MONITORDEVICEKPIREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=288, - serialized_end=393, + serialized_start=72, + serialized_end=290, ) -_INCLUDEKPIREQUEST = _descriptor.Descriptor( - name='IncludeKpiRequest', - full_name='monitoring.IncludeKpiRequest', +_MONITORKPIREQUEST = _descriptor.Descriptor( + name='MonitorKpiRequest', + full_name='monitoring.MonitorKpiRequest', filename=None, file=DESCRIPTOR, containing_type=None, create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.IncludeKpiRequest.kpi_id', index=0, + name='kpi_id', full_name='monitoring.MonitorKpiRequest.kpi_id', 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='time_stamp', full_name='monitoring.IncludeKpiRequest.time_stamp', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), + name='sampling_duration_s', full_name='monitoring.MonitorKpiRequest.sampling_duration_s', index=1, + number=2, 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='kpi_value', full_name='monitoring.IncludeKpiRequest.kpi_value', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, + name='sampling_interval_s', full_name='monitoring.MonitorKpiRequest.sampling_interval_s', index=2, + number=3, 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), @@ -253,8 +129,8 @@ _INCLUDEKPIREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=395, - serialized_end=510, + serialized_start=292, + serialized_end=404, ) @@ -285,8 +161,8 @@ _KPIID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=512, - serialized_end=550, + serialized_start=406, + serialized_end=444, ) @@ -313,33 +189,12 @@ _KPI = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='kpiDescription', full_name='monitoring.Kpi.kpiDescription', 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='kpi_value', full_name='monitoring.Kpi.kpi_value', index=3, + name='kpi_value', full_name='monitoring.Kpi.kpi_value', index=2, number=4, 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_type', full_name='monitoring.Kpi.kpi_sample_type', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=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='device_id', full_name='monitoring.Kpi.device_id', index=5, - number=6, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -352,8 +207,8 @@ _KPI = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=553, - serialized_end=767, + serialized_start=446, + serialized_end=546, ) @@ -410,8 +265,8 @@ _KPIVALUE = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[]), ], - serialized_start=769, - serialized_end=866, + serialized_start=548, + serialized_end=645, ) @@ -424,7 +279,7 @@ _KPILIST = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='kpiList', full_name='monitoring.KpiList.kpiList', index=0, + name='kpi_list', full_name='monitoring.KpiList.kpi_list', 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, @@ -442,21 +297,18 @@ _KPILIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=868, - serialized_end=911, + serialized_start=647, + serialized_end=691, ) -_CREATEKPIREQUEST.fields_by_name['device_id'].message_type = context__pb2._DEVICEID -_CREATEKPIREQUEST.fields_by_name['kpi_sample_type'].enum_type = _KPISAMPLETYPE +_KPIDESCRIPTOR.fields_by_name['kpi_sample_type'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE +_KPIDESCRIPTOR.fields_by_name['device_id'].message_type = context__pb2._DEVICEID +_KPIDESCRIPTOR.fields_by_name['endpoint_id'].message_type = context__pb2._ENDPOINTID +_KPIDESCRIPTOR.fields_by_name['service_id'].message_type = context__pb2._SERVICEID _MONITORKPIREQUEST.fields_by_name['kpi_id'].message_type = _KPIID -_MONITORDEVICEKPIREQUEST.fields_by_name['kpi'].message_type = _KPI -_INCLUDEKPIREQUEST.fields_by_name['kpi_id'].message_type = _KPIID -_INCLUDEKPIREQUEST.fields_by_name['kpi_value'].message_type = _KPIVALUE _KPIID.fields_by_name['kpi_id'].message_type = context__pb2._UUID _KPI.fields_by_name['kpi_id'].message_type = _KPIID _KPI.fields_by_name['kpi_value'].message_type = _KPIVALUE -_KPI.fields_by_name['kpi_sample_type'].enum_type = _KPISAMPLETYPE -_KPI.fields_by_name['device_id'].message_type = context__pb2._DEVICEID _KPIVALUE.oneofs_by_name['value'].fields.append( _KPIVALUE.fields_by_name['intVal']) _KPIVALUE.fields_by_name['intVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] @@ -469,24 +321,21 @@ _KPIVALUE.fields_by_name['stringVal'].containing_oneof = _KPIVALUE.oneofs_by_nam _KPIVALUE.oneofs_by_name['value'].fields.append( _KPIVALUE.fields_by_name['boolVal']) _KPIVALUE.fields_by_name['boolVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] -_KPILIST.fields_by_name['kpiList'].message_type = _KPI -DESCRIPTOR.message_types_by_name['CreateKpiRequest'] = _CREATEKPIREQUEST +_KPILIST.fields_by_name['kpi_list'].message_type = _KPI +DESCRIPTOR.message_types_by_name['KpiDescriptor'] = _KPIDESCRIPTOR DESCRIPTOR.message_types_by_name['MonitorKpiRequest'] = _MONITORKPIREQUEST -DESCRIPTOR.message_types_by_name['MonitorDeviceKpiRequest'] = _MONITORDEVICEKPIREQUEST -DESCRIPTOR.message_types_by_name['IncludeKpiRequest'] = _INCLUDEKPIREQUEST DESCRIPTOR.message_types_by_name['KpiId'] = _KPIID DESCRIPTOR.message_types_by_name['Kpi'] = _KPI DESCRIPTOR.message_types_by_name['KpiValue'] = _KPIVALUE DESCRIPTOR.message_types_by_name['KpiList'] = _KPILIST -DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) -CreateKpiRequest = _reflection.GeneratedProtocolMessageType('CreateKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _CREATEKPIREQUEST, +KpiDescriptor = _reflection.GeneratedProtocolMessageType('KpiDescriptor', (_message.Message,), { + 'DESCRIPTOR' : _KPIDESCRIPTOR, '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.CreateKpiRequest) + # @@protoc_insertion_point(class_scope:monitoring.KpiDescriptor) }) -_sym_db.RegisterMessage(CreateKpiRequest) +_sym_db.RegisterMessage(KpiDescriptor) MonitorKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorKpiRequest', (_message.Message,), { 'DESCRIPTOR' : _MONITORKPIREQUEST, @@ -495,20 +344,6 @@ MonitorKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorKpiRequest' }) _sym_db.RegisterMessage(MonitorKpiRequest) -MonitorDeviceKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorDeviceKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _MONITORDEVICEKPIREQUEST, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.MonitorDeviceKpiRequest) - }) -_sym_db.RegisterMessage(MonitorDeviceKpiRequest) - -IncludeKpiRequest = _reflection.GeneratedProtocolMessageType('IncludeKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _INCLUDEKPIREQUEST, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.IncludeKpiRequest) - }) -_sym_db.RegisterMessage(IncludeKpiRequest) - KpiId = _reflection.GeneratedProtocolMessageType('KpiId', (_message.Message,), { 'DESCRIPTOR' : _KPIID, '__module__' : 'monitoring_pb2' @@ -546,45 +381,45 @@ _MONITORINGSERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=1036, - serialized_end=1431, + serialized_start=694, + serialized_end=1065, methods=[ _descriptor.MethodDescriptor( name='CreateKpi', full_name='monitoring.MonitoringService.CreateKpi', index=0, containing_service=None, - input_type=_CREATEKPIREQUEST, + input_type=_KPIDESCRIPTOR, output_type=_KPIID, serialized_options=None, create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( - name='IncludeKpi', - full_name='monitoring.MonitoringService.IncludeKpi', + name='GetKpiDescriptor', + full_name='monitoring.MonitoringService.GetKpiDescriptor', index=1, containing_service=None, - input_type=_INCLUDEKPIREQUEST, - output_type=context__pb2._EMPTY, + input_type=_KPIID, + output_type=_KPIDESCRIPTOR, serialized_options=None, create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( - name='MonitorKpi', - full_name='monitoring.MonitoringService.MonitorKpi', + name='IncludeKpi', + full_name='monitoring.MonitoringService.IncludeKpi', index=2, containing_service=None, - input_type=_MONITORKPIREQUEST, + input_type=_KPI, output_type=context__pb2._EMPTY, serialized_options=None, create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( - name='MonitorDeviceKpi', - full_name='monitoring.MonitoringService.MonitorDeviceKpi', + name='MonitorKpi', + full_name='monitoring.MonitoringService.MonitorKpi', index=3, containing_service=None, - input_type=_MONITORDEVICEKPIREQUEST, + input_type=_MONITORKPIREQUEST, output_type=context__pb2._EMPTY, serialized_options=None, create_key=_descriptor._internal_create_key, diff --git a/src/device/requirements.in b/src/device/requirements.in index 5c38e92914207bf101ebc00b2cef453a3a85f82a..5a05d7efa6ef6964717635123756da0aead4ceff 100644 --- a/src/device/requirements.in +++ b/src/device/requirements.in @@ -3,12 +3,8 @@ apscheduler fastcache grpcio-health-checking grpcio -Jinja2 -netconf-client #1.7.3 prometheus-client pytest pytest-benchmark -python-json-logger pytz redis -xmltodict diff --git a/src/device/service/DeviceService.py b/src/device/service/DeviceService.py index ae0d5c8396157d5398751587f5e7d808b0d8f484..29fdc97ce1ba5c8d7266ecdac340dce3e3670425 100644 --- a/src/device/service/DeviceService.py +++ b/src/device/service/DeviceService.py @@ -1,28 +1,20 @@ -import grpc, logging +import grpc +import logging from concurrent import futures from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH from grpc_health.v1.health_pb2 import HealthCheckResponse from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server -from context.client.ContextClient import ContextClient -from device.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD from device.proto.device_pb2_grpc import add_DeviceServiceServicer_to_server -from .DeviceServiceServicerImpl import DeviceServiceServicerImpl -#from .MonitoringLoops import MonitoringLoops -from .driver_api.DriverInstanceCache import DriverInstanceCache +from device.service.DeviceServiceServicerImpl import DeviceServiceServicerImpl +from device.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD BIND_ADDRESS = '0.0.0.0' LOGGER = logging.getLogger(__name__) class DeviceService: - def __init__( - self, context_client : ContextClient, driver_instance_cache : DriverInstanceCache, - #monitoring_loops : MonitoringLoops, - address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, - grace_period=GRPC_GRACE_PERIOD): - - self.context_client = context_client - self.driver_instance_cache = driver_instance_cache - #self.monitoring_loops = monitoring_loops + def __init__(self, database, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, + grace_period=GRPC_GRACE_PERIOD): + self.database = database self.address = address self.port = port self.endpoint = None @@ -34,17 +26,14 @@ class DeviceService: self.server = None def start(self): - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port)) - LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format( - str(self.endpoint), str(self.max_workers))) + self.endpoint = '{}:{}'.format(self.address, self.port) + LOGGER.debug('Starting Service (tentative endpoint: {}, max_workers: {})...'.format( + self.endpoint, self.max_workers)) self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers) self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,)) - self.device_servicer = DeviceServiceServicerImpl( - self.context_client, self.driver_instance_cache, - #self.monitoring_loops - ) + self.device_servicer = DeviceServiceServicerImpl(self.database) add_DeviceServiceServicer_to_server(self.device_servicer, self.server) self.health_servicer = HealthServicer( @@ -52,15 +41,15 @@ class DeviceService: add_HealthServicer_to_server(self.health_servicer, self.server) port = self.server.add_insecure_port(self.endpoint) - self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port)) - LOGGER.info('Listening on {:s}...'.format(str(self.endpoint))) + self.endpoint = '{}:{}'.format(self.address, port) + LOGGER.info('Listening on {}...'.format(self.endpoint)) self.server.start() self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member LOGGER.debug('Service started') def stop(self): - LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period))) + LOGGER.debug('Stopping service (grace period {} seconds)...'.format(self.grace_period)) self.health_servicer.enter_graceful_shutdown() self.server.stop(self.grace_period) LOGGER.debug('Service stopped') diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py index 6c559fda37b7e4f8798be3747261e559a3eb0953..e07925aae31b7e2f275360e61fee3a8fe1347a2e 100644 --- a/src/device/service/DeviceServiceServicerImpl.py +++ b/src/device/service/DeviceServiceServicerImpl.py @@ -1,290 +1,206 @@ -import grpc, json, logging -from typing import Any, List, Tuple -from google.protobuf.json_format import MessageToDict -from common.orm.Database import Database -from common.orm.Factory import get_database_backend -from common.orm.HighLevel import get_object, update_or_create_object -from common.orm.backend.BackendEnum import BackendEnum -from common.orm.backend.Tools import key_to_str -from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method -from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException, OperationFailedException -from context.client.ContextClient import ContextClient -from device.proto.context_pb2 import ConfigActionEnum, Device, DeviceConfig, DeviceId, Empty -#from device.proto.device_pb2 import MonitoringSettings +import grpc, logging +from prometheus_client import Counter, Histogram +from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID +from common.database.api.Database import Database +from common.database.api.context.topology.device.OperationalStatus import OperationalStatus +from common.exceptions.ServiceException import ServiceException +from device.proto.context_pb2 import DeviceId, Device, Empty +from device.proto.device_pb2 import MonitoringSettings from device.proto.device_pb2_grpc import DeviceServiceServicer -#from .MonitoringLoops import MonitoringLoops -from .database.ConfigModel import ( - ConfigModel, ConfigRuleModel, ORM_ConfigActionEnum, get_config_rules, grpc_config_rules_to_raw, update_config) -from .database.DatabaseTools import ( - delete_device_from_context, get_device_driver_filter_fields, sync_device_from_context, sync_device_to_context, - update_device_in_local_database) -from .database.DeviceModel import DeviceModel, DriverModel -from .database.EndPointModel import EndPointModel -#from .database.KpiModel import KpiModel -#from .database.KpiSampleType import grpc_to_enum__kpi_sample_type -from .driver_api._Driver import _Driver, RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES -from .driver_api.DriverInstanceCache import DriverInstanceCache -from .driver_api.Tools import ( - check_delete_errors, check_set_errors, - #check_subscribe_errors, check_unsubscribe_errors -) +from device.service.Tools import check_device_id_request, check_device_request LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'Device' -METHOD_NAMES = ['AddDevice', 'ConfigureDevice', 'DeleteDevice', 'GetInitialConfig', 'MonitorDeviceKpi'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +ADDDEVICE_COUNTER_STARTED = Counter ('device_adddevice_counter_started', + 'Device:AddDevice counter of requests started' ) +ADDDEVICE_COUNTER_COMPLETED = Counter ('device_adddevice_counter_completed', + 'Device:AddDevice counter of requests completed') +ADDDEVICE_COUNTER_FAILED = Counter ('device_adddevice_counter_failed', + 'Device:AddDevice counter of requests failed' ) +ADDDEVICE_HISTOGRAM_DURATION = Histogram('device_adddevice_histogram_duration', + 'Device:AddDevice histogram of request duration') + +CONFIGUREDEVICE_COUNTER_STARTED = Counter ('device_configuredevice_counter_started', + 'Device:ConfigureDevice counter of requests started' ) +CONFIGUREDEVICE_COUNTER_COMPLETED = Counter ('device_configuredevice_counter_completed', + 'Device:ConfigureDevice counter of requests completed') +CONFIGUREDEVICE_COUNTER_FAILED = Counter ('device_configuredevice_counter_failed', + 'Device:ConfigureDevice counter of requests failed' ) +CONFIGUREDEVICE_HISTOGRAM_DURATION = Histogram('device_configuredevice_histogram_duration', + 'Device:ConfigureDevice histogram of request duration') + +DELETEDEVICE_COUNTER_STARTED = Counter ('device_deletedevice_counter_started', + 'Device:DeleteDevice counter of requests started' ) +DELETEDEVICE_COUNTER_COMPLETED = Counter ('device_deletedevice_counter_completed', + 'Device:DeleteDevice counter of requests completed') +DELETEDEVICE_COUNTER_FAILED = Counter ('device_deletedevice_counter_failed', + 'Device:DeleteDevice counter of requests failed' ) +DELETEDEVICE_HISTOGRAM_DURATION = Histogram('device_deletedevice_histogram_duration', + 'Device:DeleteDevice histogram of request duration') + +MONITORDEVICEKPI_COUNTER_STARTED = Counter ('device_monitordevicekpi_counter_started', + 'Device:MonitorDeviceKpi counter of requests started' ) +MONITORDEVICEKPI_COUNTER_COMPLETED = Counter ('device_monitordevicekpi_counter_completed', + 'Device:MonitorDeviceKpi counter of requests completed') +MONITORDEVICEKPI_COUNTER_FAILED = Counter ('device_monitordevicekpi_counter_failed', + 'Device:MonitorDeviceKpi counter of requests failed' ) +MONITORDEVICEKPI_HISTOGRAM_DURATION = Histogram('device_monitordevicekpi_histogram_duration', + 'Device:MonitorDeviceKpi histogram of request duration') -class DeviceServiceServicerImpl(DeviceServiceServicer): - def __init__( - self, context_client : ContextClient, driver_instance_cache : DriverInstanceCache, - #monitoring_loops : MonitoringLoops - ): +class DeviceServiceServicerImpl(DeviceServiceServicer): + def __init__(self, database : Database): LOGGER.debug('Creating Servicer...') - self.context_client = context_client - self.database = Database(get_database_backend(backend=BackendEnum.INMEMORY)) - self.driver_instance_cache = driver_instance_cache - #self.monitoring_loops = monitoring_loops + self.database = database LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) - def AddDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId: - device_id = request.device_id - device_uuid = device_id.device_uuid.uuid - - connection_config_rules = {} - unexpected_config_rules = [] - for config_rule in request.device_config.config_rules: - if (config_rule.action == ConfigActionEnum.CONFIGACTION_SET) and \ - (config_rule.resource_key.startswith('_connect/')): - connection_config_rules[config_rule.resource_key.replace('_connect/', '')] = config_rule.resource_value - else: - unexpected_config_rules.append(config_rule) - if len(unexpected_config_rules) > 0: - unexpected_config_rules = MessageToDict( - request.device_config, including_default_value_fields=True, - preserving_proto_field_name=True, use_integers_for_enums=True) - unexpected_config_rules = unexpected_config_rules['config_rules'] - unexpected_config_rules = list(filter( - lambda cr: cr['resource_key'].replace('_connect/', '') not in connection_config_rules, - unexpected_config_rules)) - str_unexpected_config_rules = json.dumps(unexpected_config_rules, sort_keys=True) - raise InvalidArgumentException( - 'device.device_config.config_rules', str_unexpected_config_rules, - extra_details='RPC method AddDevice only accepts connection Config Rules that should start '\ - 'with "_connect/" tag. Others should be configured after adding the device.') - - if len(request.device_endpoints) > 0: - unexpected_endpoints = MessageToDict( - request.device_endpoints, including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=True) - str_unexpected_endpoints = json.dumps(unexpected_endpoints, sort_keys=True) - raise InvalidArgumentException( - 'device.device_endpoints', str_unexpected_endpoints, - extra_details='RPC method AddDevice does not accept endpoints. Endpoints are discovered through '\ - 'interrogation of the physical device.') - - # Remove device configuration - json_request = MessageToDict( - request, including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=True) - json_request['device_config'] = {} - request = Device(**json_request) - - sync_device_from_context(device_uuid, self.context_client, self.database) - db_device,_ = update_device_in_local_database(self.database, request) - - driver_filter_fields = get_device_driver_filter_fields(db_device) - - address = connection_config_rules.pop('address', None) - port = connection_config_rules.pop('port', None) - driver : _Driver = self.driver_instance_cache.get( - device_uuid, filter_fields=driver_filter_fields, address=address, port=port, - settings=connection_config_rules) - driver.Connect() - - endpoints = driver.GetConfig([RESOURCE_ENDPOINTS]) - for _, resource_value in endpoints: - endpoint_uuid = resource_value.get('name') - endpoint_type = resource_value.get('type') - str_endpoint_key = key_to_str([device_uuid, endpoint_uuid]) - update_or_create_object( - self.database, EndPointModel, str_endpoint_key, { - 'device_fk' : db_device, - 'endpoint_uuid': endpoint_uuid, - 'endpoint_type': endpoint_type, - }) - - running_config_rules = driver.GetConfig([RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES]) - running_config_rules = [ - (ORM_ConfigActionEnum.SET, config_rule[0], json.dumps(config_rule[1], sort_keys=True)) - for config_rule in running_config_rules - ] - #for running_config_rule in running_config_rules: - # LOGGER.info('[AddDevice] running_config_rule: {:s}'.format(str(running_config_rule))) - - update_config(self.database, device_uuid, 'running', running_config_rules) - - initial_config_rules = driver.GetInitialConfig() - update_config(self.database, device_uuid, 'initial', initial_config_rules) - - sync_device_to_context(db_device, self.context_client) - return DeviceId(**db_device.dump_id()) - - @safe_and_metered_rpc_method(METRICS, LOGGER) - def ConfigureDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId: - device_id = request.device_id - device_uuid = device_id.device_uuid.uuid - - sync_device_from_context(device_uuid, self.context_client, self.database) - - context_config_rules = get_config_rules(self.database, device_uuid, 'running') - context_config_rules = {config_rule[1]: config_rule[2] for config_rule in context_config_rules} - LOGGER.info('[ConfigureDevice] context_config_rules = {:s}'.format(str(context_config_rules))) - - db_device,_ = update_device_in_local_database(self.database, request) - - request_config_rules = grpc_config_rules_to_raw(request.device_config.config_rules) - LOGGER.info('[ConfigureDevice] request_config_rules = {:s}'.format(str(request_config_rules))) - - resources_to_set : List[Tuple[str, Any]] = [] # key, value - resources_to_delete : List[Tuple[str, Any]] = [] # key, value - - for config_rule in request_config_rules: - action, key, value = config_rule - if action == ORM_ConfigActionEnum.SET: - if (key not in context_config_rules) or (context_config_rules[key] != value): - resources_to_set.append((key, value)) - elif action == ORM_ConfigActionEnum.DELETE: - if key in context_config_rules: - resources_to_delete.append((key, value)) - - LOGGER.info('[ConfigureDevice] resources_to_set = {:s}'.format(str(resources_to_set))) - LOGGER.info('[ConfigureDevice] resources_to_delete = {:s}'.format(str(resources_to_delete))) - - # TODO: use of datastores (might be virtual ones) to enable rollbacks - - errors = [] - - driver : _Driver = self.driver_instance_cache.get(device_uuid) - if driver is None: - errors.append('Device({:s}) has not been added to this Device instance'.format(str(device_uuid))) - - if len(errors) == 0: - results_setconfig = driver.SetConfig(resources_to_set) - errors.extend(check_set_errors(resources_to_set, results_setconfig)) - - if len(errors) == 0: - results_deleteconfig = driver.DeleteConfig(resources_to_delete) - errors.extend(check_delete_errors(resources_to_delete, results_deleteconfig)) - - if len(errors) > 0: - raise OperationFailedException('ConfigureDevice', extra_details=errors) - - sync_device_to_context(db_device, self.context_client) - return DeviceId(**db_device.dump_id()) - - @safe_and_metered_rpc_method(METRICS, LOGGER) - def DeleteDevice(self, request : DeviceId, context : grpc.ServicerContext) -> Empty: - device_uuid = request.device_uuid.uuid - - sync_device_from_context(device_uuid, self.context_client, self.database) - db_device : DeviceModel = get_object(self.database, DeviceModel, device_uuid, raise_if_not_found=False) - if db_device is None: return Empty() - - self.driver_instance_cache.delete(device_uuid) - delete_device_from_context(db_device, self.context_client) - - for db_endpoint_pk,_ in db_device.references(EndPointModel): - EndPointModel(self.database, db_endpoint_pk).delete() - - for db_driver_pk,_ in db_device.references(DriverModel): - DriverModel(self.database, db_driver_pk).delete() - - db_initial_config = ConfigModel(self.database, db_device.device_initial_config_fk) - for db_config_rule_pk,_ in db_initial_config.references(ConfigRuleModel): - ConfigRuleModel(self.database, db_config_rule_pk).delete() - - db_running_config = ConfigModel(self.database, db_device.device_running_config_fk) - for db_config_rule_pk,_ in db_running_config.references(ConfigRuleModel): - ConfigRuleModel(self.database, db_config_rule_pk).delete() - - db_device.delete() - db_initial_config.delete() - db_running_config.delete() - return Empty() - - @safe_and_metered_rpc_method(METRICS, LOGGER) - def GetInitialConfig(self, request : DeviceId, context : grpc.ServicerContext) -> DeviceConfig: - device_uuid = request.device_uuid.uuid - - sync_device_from_context(device_uuid, self.context_client, self.database) - db_device : DeviceModel = get_object(self.database, DeviceModel, device_uuid, raise_if_not_found=False) - - config_rules = {} if db_device is None else db_device.dump_initial_config() - return DeviceConfig(config_rules=config_rules) - -# # Code under implemention and testing -# @safe_and_metered_rpc_method(METRICS, LOGGER) -# def MonitorDeviceKpi(self, request : MonitoringSettings, context : grpc.ServicerContext) -> Empty: -# kpi_uuid = request.kpi_id.kpi_id.uuid -# -# device_uuid = request.kpi_descriptor.device_id.device_uuid.uuid -# db_device : DeviceModel = get_object(self.database, DeviceModel, device_uuid, raise_if_not_found=False) -# -# endpoint_id = request.kpi_descriptor.endpoint_id -# endpoint_uuid = endpoint_id.endpoint_uuid.uuid -# endpoint_device_uuid = endpoint_id.device_id.device_uuid.uuid -# if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid -# str_endpoint_key = key_to_str([device_uuid, endpoint_uuid]) -# endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid -# endpoint_topology_uuid = endpoint_id.topology_id.topology_uuid.uuid -# if len(endpoint_topology_context_uuid) > 0 and len(endpoint_topology_uuid) > 0: -# str_topology_key = key_to_str([endpoint_topology_context_uuid, endpoint_topology_uuid]) -# str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':') -# db_endpoint : EndPointModel = get_object( -# self.database, EndPointModel, str_endpoint_key, raise_if_not_found=False) -# -# #db_kpi_prev = get_object(self.database, KpiModel, kpi_uuid, raise_if_not_found=False) -# result : Tuple[KpiModel, bool] = update_or_create_object(self.database, KpiModel, kpi_uuid, { -# 'kpi_uuid' : request.kpi_id.kpi_id.uuid, -# 'kpi_description' : request.kpi_descriptor.kpi_description, -# 'kpi_sample_type' : grpc_to_enum__kpi_sample_type(request.kpi_descriptor.kpi_sample_type), -# 'device_fk' : db_device, -# 'endpoint_fk' : db_endpoint, -# 'sampling_duration': request.sampling_duration_s, -# 'sampling_interval': request.sampling_interval_s, -# }) -# db_kpi, updated = result -# -# driver : _Driver = self.driver_instance_cache.get(device_uuid) -# if driver is None: -# msg = 'Device({:s}) has not been added to this Device instance'.format(str(device_uuid)) -# raise OperationFailedException('ConfigureDevice', extra_details=msg) -# -# sampling_resource = driver.GetResource(db_endpoint.endpoint_uuid) -# -# #resources_to_subscribe : List[Tuple[str, float, float]] = [] # key, sampling_duration, sampling_interval -# #resources_to_unsubscribe : List[Tuple[str, float, float]] = [] # key, sampling_duration, sampling_interval -# #LOGGER.info('[ConfigureDevice] resources_to_subscribe = {:s}'.format(str(resources_to_subscribe))) -# #LOGGER.info('[ConfigureDevice] resources_to_unsubscribe = {:s}'.format(str(resources_to_unsubscribe))) -# # TODO: Implement configuration of subscriptions -# -# #if len(errors) == 0: -# # results_subscribestate = driver.SubscribeState(resources_to_subscribe) -# # errors.extend(check_subscribe_errors(resources_to_delete, results_subscribestate)) -# -# #if len(errors) == 0: -# # results_unsubscribestate = driver.UnsubscribeState(resources_to_unsubscribe) -# # errors.extend(check_unsubscribe_errors(resources_to_delete, results_unsubscribestate)) -# -# results = driver.SubscribeState([ -# (sampling_resource, db_kpi.sampling_duration, db_kpi.sampling_interval), -# ]) -# assert len(results) == 4 -# for result in results: assert isinstance(result, bool) and result -# -# self.monitoring_loops.add(device_uuid, driver) -# -# return Empty() + @ADDDEVICE_HISTOGRAM_DURATION.time() + def AddDevice(self, request : Device, grpc_context : grpc.ServicerContext) -> DeviceId: + ADDDEVICE_COUNTER_STARTED.inc() + try: + LOGGER.debug('AddDevice request: {}'.format(str(request))) + + # ----- Validate request data and pre-conditions ----------------------------------------------------------- + device_id, device_type, device_config, device_opstat, db_endpoints_ports = \ + check_device_request('AddDevice', request, self.database, LOGGER) + + # ----- Implement changes in the database ------------------------------------------------------------------ + db_context = self.database.context(DEFAULT_CONTEXT_ID).create() + db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).create() + db_device = db_topology.device(device_id).create(device_type, device_config, device_opstat) + for db_endpoint,port_type in db_endpoints_ports: + db_endpoint.create(port_type) + + # ----- Compose reply -------------------------------------------------------------------------------------- + reply = DeviceId(**db_device.dump_id()) + LOGGER.debug('AddDevice reply: {}'.format(str(reply))) + ADDDEVICE_COUNTER_COMPLETED.inc() + return reply + except ServiceException as e: + LOGGER.exception('AddDevice exception') + ADDDEVICE_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: # pragma: no cover + LOGGER.exception('AddDevice exception') + ADDDEVICE_COUNTER_FAILED.inc() + grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) + + @CONFIGUREDEVICE_HISTOGRAM_DURATION.time() + def ConfigureDevice(self, request : Device, grpc_context : grpc.ServicerContext) -> DeviceId: + CONFIGUREDEVICE_COUNTER_STARTED.inc() + try: + LOGGER.debug('ConfigureDevice request: {}'.format(str(request))) + + # ----- Validate request data and pre-conditions ----------------------------------------------------------- + device_id, device_type, device_config, device_opstat, db_endpoints_ports = \ + check_device_request('UpdateDevice', request, self.database, LOGGER) + + # ----- Implement changes in the database ------------------------------------------------------------------ + db_context = self.database.context(DEFAULT_CONTEXT_ID).create() + db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).create() + db_device = db_topology.device(device_id) + + db_device_attributes = db_device.attributes.get(attributes=['device_type']) + # should not happen, device creation through Database API ensures all fields are always present + if len(db_device_attributes) == 0: # pragma: no cover + msg = 'Attribute device_type for Device({}) does not exist in the database.' # pragma: no cover + msg = msg.format(device_id) # pragma: no cover + raise ServiceException(grpc.StatusCode.FAILED_PRECONDITION, msg) # pragma: no cover + + db_device_type = db_device_attributes.get('device_type') + # should not happen, device creation through Database API ensures all fields are always present + if len(db_device_type) == 0: # pragma: no cover + msg = 'Attribute device_type for Device({}) is empty in the database.' # pragma: no cover + msg = msg.format(device_id) # pragma: no cover + raise ServiceException(grpc.StatusCode.FAILED_PRECONDITION, msg) # pragma: no cover + + if db_device_type != device_type: + msg = 'Device({}) has Type({}) in the database. Cannot be changed to Type({}).' + msg = msg.format(device_id, db_device_type, device_type) + raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg) + + if len(db_endpoints_ports) > 0: + msg = 'Endpoints belonging to Device({}) cannot be modified.' + msg = msg.format(device_id) + raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg) + + update_attributes = {} + + if len(device_config) > 0: + update_attributes['device_config'] = device_config + + if device_opstat != OperationalStatus.KEEP_STATE: + update_attributes['device_operational_status'] = device_opstat + + if len(update_attributes) == 0: + msg = ' '.join([ + 'Any change has been requested for Device({}).', + 'Either specify a new configuration or a new device operational status.', + ]) + msg = msg.format(device_id) + raise ServiceException(grpc.StatusCode.ABORTED, msg) + + db_device.update(update_attributes=update_attributes) + + # ----- Compose reply -------------------------------------------------------------------------------------- + reply = DeviceId(**db_device.dump_id()) + LOGGER.debug('ConfigureDevice reply: {}'.format(str(reply))) + CONFIGUREDEVICE_COUNTER_COMPLETED.inc() + return reply + except ServiceException as e: + LOGGER.exception('ConfigureDevice exception') + CONFIGUREDEVICE_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: # pragma: no cover + LOGGER.exception('ConfigureDevice exception') + CONFIGUREDEVICE_COUNTER_FAILED.inc() + grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) + + @DELETEDEVICE_HISTOGRAM_DURATION.time() + def DeleteDevice(self, request : DeviceId, grpc_context : grpc.ServicerContext) -> Empty: + DELETEDEVICE_COUNTER_STARTED.inc() + try: + LOGGER.debug('DeleteDevice request: {}'.format(str(request))) + + # ----- Validate request data and pre-conditions ----------------------------------------------------------- + device_id = check_device_id_request('DeleteDevice', request, self.database, LOGGER) + + # ----- Implement changes in the database ------------------------------------------------------------------ + db_context = self.database.context(DEFAULT_CONTEXT_ID).create() + db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).create() + db_topology.device(device_id).delete() + + # ----- Compose reply -------------------------------------------------------------------------------------- + reply = Empty() + LOGGER.debug('DeleteDevice reply: {}'.format(str(reply))) + DELETEDEVICE_COUNTER_COMPLETED.inc() + return reply + except ServiceException as e: + LOGGER.exception('DeleteDevice exception') + DELETEDEVICE_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: # pragma: no cover + LOGGER.exception('DeleteDevice exception') + DELETEDEVICE_COUNTER_FAILED.inc() + grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) + + @MONITORDEVICEKPI_HISTOGRAM_DURATION.time() + def MonitorDeviceKpi(self, request : MonitoringSettings, grpc_context : grpc.ServicerContext) -> Empty: + MONITORDEVICEKPI_COUNTER_STARTED.inc() + try: + LOGGER.debug('MonitorDeviceKpi request: {}'.format(str(request))) + + # ---- Implement method ------------------------------------------------------------------------------------ + + reply = Empty() + LOGGER.debug('MonitorDeviceKpi reply: {}'.format(str(reply))) + MONITORDEVICEKPI_COUNTER_COMPLETED.inc() + return reply + except ServiceException as e: + LOGGER.exception('MonitorDeviceKpi exception') + MONITORDEVICEKPI_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: + LOGGER.exception('MonitorDeviceKpi exception') + MONITORDEVICEKPI_COUNTER_FAILED.inc() + grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) diff --git a/src/device/service/MonitoringLoops.py b/src/device/service/MonitoringLoops.py deleted file mode 100644 index 658e1de0a99db161fabb88733182d3386b165cbd..0000000000000000000000000000000000000000 --- a/src/device/service/MonitoringLoops.py +++ /dev/null @@ -1,83 +0,0 @@ -#import logging, queue, threading -#from typing import Dict -#from monitoring.client.monitoring_client import MonitoringClient -#from monitoring.proto.monitoring_pb2 import Kpi -#from .driver_api._Driver import _Driver -# -#LOGGER = logging.getLogger(__name__) -#QUEUE_GET_WAIT_TIMEOUT = 0.5 -# -#class MonitoringLoop: -# def __init__(self, driver : _Driver, samples_queue : queue.Queue) -> None: -# self._driver = driver -# self._samples_queue = samples_queue -# self._running = threading.Event() -# self._terminate = threading.Event() -# self._samples_stream = self._driver.GetState(blocking=True) -# self._collector_thread = threading.Thread(target=self._collect, daemon=False) -# -# def _collect(self) -> None: -# for sample in self._samples_stream: -# if self._terminate.is_set(): break -# LOGGER.info('[MonitoringLoop:_collect] sample={:s}'.format(str(sample))) -# # TODO: add timestamp (if not present) -# self._samples_queue.put_nowait(sample) -# -# def start(self): -# self._collector_thread.start() -# self._running.set() -# -# @property -# def is_running(self): return self._running.is_set() -# -# def stop(self): -# self._terminate.set() -# self._samples_stream.cancel() -# self._collector_thread.join() -# -#class MonitoringLoops: -# def __init__(self, monitoring_client : MonitoringClient) -> None: -# self._monitoring_client = monitoring_client -# self._samples_queue = queue.Queue() -# self._running = threading.Event() -# self._terminate = threading.Event() -# self._lock = threading.Lock() -# self._device_uuid__to__monitoring_loop : Dict[str, MonitoringLoop] = {} -# self._exporter_thread = threading.Thread(target=self._export, daemon=False) -# -# def add(self, device_uuid : str, driver : _Driver) -> None: -# with self._lock: -# monitoring_loop = self._device_uuid__to__monitoring_loop.get(device_uuid) -# if (monitoring_loop is not None) and monitoring_loop.is_running: return -# monitoring_loop = MonitoringLoop(driver, self._samples_queue) -# self._device_uuid__to__monitoring_loop[device_uuid] = monitoring_loop -# monitoring_loop.start() -# -# def remove(self, device_uuid : str) -> None: -# with self._lock: -# monitoring_loop = self._device_uuid__to__monitoring_loop.get(device_uuid) -# if monitoring_loop is None: return -# if monitoring_loop.is_running: monitoring_loop.stop() -# self._device_uuid__to__monitoring_loop.pop(device_uuid, None) -# -# def start(self): -# self._exporter_thread.start() -# self._running.set() -# -# @property -# def is_running(self): return self._running.is_set() -# -# def stop(self): -# self._terminate.set() -# self._exporter_thread.join() -# -# def _export(self) -> None: -# while not self._terminate.is_set(): -# try: -# sample = self._samples_queue.get(block=True, timeout=QUEUE_GET_WAIT_TIMEOUT) -# LOGGER.info('[MonitoringLoops:_export] sample={:s}'.format(str(sample))) -# except queue.Empty: -# continue -# # TODO: find in database the KpiId, format KPI and send to Monitoring -# kpi_data = {} -# self._monitoring_client.IncludeKpi(Kpi(**kpi_data)) diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py new file mode 100644 index 0000000000000000000000000000000000000000..26b5a5d90c34d7e23e52e12642178b18338891b2 --- /dev/null +++ b/src/device/service/Tools.py @@ -0,0 +1,120 @@ +import grpc, logging +from typing import Dict, List, Set, Tuple +from common.Checkers import chk_options, chk_string +from common.database.api.Database import Database +from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID +from common.database.api.context.topology.device.Endpoint import Endpoint +from common.database.api.context.topology.device.OperationalStatus import OperationalStatus, \ + operationalstatus_enum_values, to_operationalstatus_enum +from common.exceptions.ServiceException import ServiceException +from common.tools.service.DeviceCheckers import check_device_endpoint_exists +from common.tools.service.EndpointIdCheckers import check_endpoint_id +from common.tools.service.EnumCheckers import check_enum +from common.tools.service.DeviceCheckers import check_device_exists, check_device_not_exists +from device.proto.context_pb2 import Device, DeviceId + +# For each method name, define acceptable device operational statuses. Empty set means accept all. +ACCEPTED_DEVICE_OPERATIONAL_STATUSES : Dict[str, Set[OperationalStatus]] = { + 'AddDevice': set([OperationalStatus.ENABLED, OperationalStatus.DISABLED]), + 'UpdateDevice': set([OperationalStatus.KEEP_STATE, OperationalStatus.ENABLED, OperationalStatus.DISABLED]), +} + +def _check_device_exists(method_name : str, database : Database, device_id : str): + if method_name in ['AddDevice']: + check_device_not_exists(database, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id) + elif method_name in ['UpdateDevice', 'DeleteDevice']: + check_device_exists(database, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id) + else: # pragma: no cover (test requires malforming the code) + msg = 'Unexpected condition [_check_device_exists(method_name={}, device_id={})]' + msg = msg.format(str(method_name), str(device_id)) + raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg) + +def _check_device_endpoint_exists_or_get_pointer( + method_name : str, database : Database, parent_name : str, device_id : str, endpoint_id : str): + + if method_name in ['AddDevice']: + db_context = database.context(DEFAULT_CONTEXT_ID) + db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID) + db_device = db_topology.device(device_id) + return db_device.endpoint(endpoint_id) + elif method_name in ['UpdateDevice', 'DeleteDevice']: + return check_device_endpoint_exists( + database, parent_name, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id, endpoint_id) + else: # pragma: no cover (test requires malforming the code) + msg = 'Unexpected condition [_check_device_exists(method_name={}, device_id={})]' + msg = msg.format(str(method_name), str(device_id)) + raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg) + +def check_device_operational_status(method_name : str, value : str) -> OperationalStatus: + return check_enum( + 'OperationalStatus', method_name, value, to_operationalstatus_enum, ACCEPTED_DEVICE_OPERATIONAL_STATUSES) + +def check_device_request( + method_name : str, request : Device, database : Database, logger : logging.Logger + ) -> Tuple[str, str, str, OperationalStatus, List[Tuple[Endpoint, str]]]: + + # ----- Parse attributes ------------------------------------------------------------------------------------------- + try: + device_id = chk_string ('device.device_id.device_id.uuid', + request.device_id.device_id.uuid, + allow_empty=False) + device_type = chk_string ('device.device_type', + request.device_type, + allow_empty=False) + device_config = chk_string ('device.device_config.device_config', + request.device_config.device_config, + allow_empty=True) + device_opstat = chk_options('device.devOperationalStatus', + request.devOperationalStatus, + operationalstatus_enum_values()) + except Exception as e: + logger.exception('Invalid arguments:') + raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e)) + + device_opstat = check_device_operational_status(method_name, device_opstat) + + # ----- Check if device exists in database ------------------------------------------------------------------------- + _check_device_exists(method_name, database, device_id) + + # ----- Parse endpoints and check if they exist in the database as device endpoints -------------------------------- + add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]] = {} + db_endpoints__port_types : List[Tuple[Endpoint, str]] = [] + for endpoint_number,endpoint in enumerate(request.endpointList): + parent_name = 'Endpoint(#{}) of Context({})/Topology({})/Device({})' + parent_name = parent_name.format(endpoint_number, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id) + + _, ep_device_id, ep_port_id = check_endpoint_id( + logger, endpoint_number, parent_name, endpoint.port_id, add_topology_devices_endpoints, + predefined_device_id=device_id, acceptable_device_ids=set([device_id]), + prevent_same_device_multiple_times=False) + + try: + ep_port_type = chk_string('endpoint[#{}].port_type'.format(endpoint_number), + endpoint.port_type, + allow_empty=False) + except Exception as e: + logger.exception('Invalid arguments:') + raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e)) + + db_endpoint = _check_device_endpoint_exists_or_get_pointer( + method_name, database, parent_name, ep_device_id, ep_port_id) + db_endpoints__port_types.append((db_endpoint, ep_port_type)) + + return device_id, device_type, device_config, device_opstat, db_endpoints__port_types + +def check_device_id_request( + method_name : str, request : DeviceId, database : Database, logger : logging.Logger) -> str: + + # ----- Parse attributes ------------------------------------------------------------------------------------------- + try: + device_id = chk_string('device_id.device_id.uuid', + request.device_id.uuid, + allow_empty=False) + except Exception as e: + logger.exception('Invalid arguments:') + raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e)) + + # ----- Check if device exists in database --------------------------------------------------------------------------- + _check_device_exists(method_name, database, device_id) + + return device_id diff --git a/src/device/service/__main__.py b/src/device/service/__main__.py index 77572c51f9064712c2d9e4d9ccc9e943fe0df1c7..6958d7e434f3f1765f209dfe63e4748cda4b7c1c 100644 --- a/src/device/service/__main__.py +++ b/src/device/service/__main__.py @@ -1,83 +1,52 @@ import logging, signal, sys, threading from prometheus_client import start_http_server from common.Settings import get_setting -from context.client.ContextClient import ContextClient -from device.Config import ( - CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, - METRICS_PORT, MONITORING_SERVICE_HOST, MONITORING_SERVICE_PORT) -#from monitoring.client.monitoring_client import MonitoringClient -from .DeviceService import DeviceService -#from .MonitoringLoops import MonitoringLoops -from .driver_api.DriverFactory import DriverFactory -from .driver_api.DriverInstanceCache import DriverInstanceCache -from .drivers import DRIVERS +from common.database.Factory import get_database +from device.service.DeviceService import DeviceService +from device.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT terminate = threading.Event() -LOGGER = None +logger = None -def signal_handler(signal, frame): # pylint: disable=redefined-outer-name - LOGGER.warning('Terminate signal received') +def signal_handler(signal, frame): + global terminate, logger + logger.warning('Terminate signal received') terminate.set() def main(): - global LOGGER # pylint: disable=global-statement + global terminate, logger - grpc_service_port = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT ) - max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) - grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD ) - log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) - metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) - context_service_host = get_setting('CONTEXTSERVICE_SERVICE_HOST', default=CONTEXT_SERVICE_HOST ) - context_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC', default=CONTEXT_SERVICE_PORT ) - monitoring_service_host = get_setting('MONITORINGSERVICE_SERVICE_HOST', default=MONITORING_SERVICE_HOST) - monitoring_service_port = get_setting('MONITORINGSERVICE_SERVICE_PORT_GRPC', default=MONITORING_SERVICE_PORT) + service_port = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT) + max_workers = get_setting('MAX_WORKERS', default=GRPC_MAX_WORKERS ) + grace_period = get_setting('GRACE_PERIOD', default=GRPC_GRACE_PERIOD) + log_level = get_setting('LOG_LEVEL', default=LOG_LEVEL ) + metrics_port = get_setting('METRICS_PORT', default=METRICS_PORT ) logging.basicConfig(level=log_level) - LOGGER = logging.getLogger(__name__) + logger = logging.getLogger(__name__) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) - LOGGER.info('Starting...') + logger.info('Starting...') # Start metrics server start_http_server(metrics_port) - # Initialize Context Client - if context_service_host is None or context_service_port is None: - raise Exception('Wrong address({:s}):port({:s}) of Context component'.format( - str(context_service_host), str(context_service_port))) - context_client = ContextClient(context_service_host, context_service_port) - - ## Initialize Monitoring Client - #if monitoring_service_host is None or monitoring_service_port is None: - # raise Exception('Wrong address({:s}):port({:s}) of Monitoring component'.format( - # str(monitoring_service_host), str(monitoring_service_port))) - #monitoring_client = MonitoringClient(monitoring_service_host, monitoring_service_port) - - # Initialize Driver framework - driver_factory = DriverFactory(DRIVERS) - driver_instance_cache = DriverInstanceCache(driver_factory) - #monitoring_loops = MonitoringLoops(monitoring_client) + # Get database instance + database = get_database() # Starting device service - grpc_service = DeviceService( - context_client, driver_instance_cache, - #monitoring_loops, - port=grpc_service_port, max_workers=max_workers, - grace_period=grace_period) + grpc_service = DeviceService(database, port=service_port, max_workers=max_workers, grace_period=grace_period) grpc_service.start() - #monitoring_loops.start() # Wait for Ctrl+C or termination signal while not terminate.wait(timeout=0.1): pass - LOGGER.info('Terminating...') - #monitoring_loops.stop() + logger.info('Terminating...') grpc_service.stop() - driver_instance_cache.terminate() - LOGGER.info('Bye') + logger.info('Bye') return 0 if __name__ == '__main__': diff --git a/src/device/service/database/ConfigModel.py b/src/device/service/database/ConfigModel.py deleted file mode 100644 index 82697bfbae7d1f58fdc851aa66f86f0fc78a767e..0000000000000000000000000000000000000000 --- a/src/device/service/database/ConfigModel.py +++ /dev/null @@ -1,98 +0,0 @@ -import functools, logging, operator -from enum import Enum -from typing import Dict, List, Tuple, Union -from common.orm.Database import Database -from common.orm.HighLevel import get_object, get_or_create_object, update_or_create_object -from common.orm.backend.Tools import key_to_str -from common.orm.fields.EnumeratedField import EnumeratedField -from common.orm.fields.ForeignKeyField import ForeignKeyField -from common.orm.fields.IntegerField import IntegerField -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model -from device.proto.context_pb2 import ConfigActionEnum -from .Tools import fast_hasher, grpc_to_enum, remove_dict_key - -LOGGER = logging.getLogger(__name__) - -class ORM_ConfigActionEnum(Enum): - UNDEFINED = ConfigActionEnum.CONFIGACTION_UNDEFINED - SET = ConfigActionEnum.CONFIGACTION_SET - DELETE = ConfigActionEnum.CONFIGACTION_DELETE - -grpc_to_enum__config_action = functools.partial( - grpc_to_enum, ConfigActionEnum, ORM_ConfigActionEnum) - -class ConfigModel(Model): # pylint: disable=abstract-method - pk = PrimaryKeyField() - - def dump(self) -> List[Dict]: - db_config_rule_pks = self.references(ConfigRuleModel) - config_rules = [ConfigRuleModel(self.database, pk).dump(include_position=True) for pk,_ in db_config_rule_pks] - config_rules = sorted(config_rules, key=operator.itemgetter('position')) - return [remove_dict_key(config_rule, 'position') for config_rule in config_rules] - -class ConfigRuleModel(Model): # pylint: disable=abstract-method - pk = PrimaryKeyField() - config_fk = ForeignKeyField(ConfigModel) - position = IntegerField(min_value=0, required=True) - action = EnumeratedField(ORM_ConfigActionEnum, required=True) - key = StringField(required=True, allow_empty=False) - value = StringField(required=False, allow_empty=True) - - def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ - result = { - 'action': self.action.value, - 'resource_key': self.key, - 'resource_value': self.value, - } - if include_position: result['position'] = self.position - return result - -def delete_all_config_rules(database : Database, db_parent_pk : str, config_name : str) -> None: - str_config_key = key_to_str([db_parent_pk, config_name], separator=':') - db_config : ConfigModel = get_object(database, ConfigModel, str_config_key, raise_if_not_found=False) - if db_config is None: return - db_config_rule_pks = db_config.references(ConfigRuleModel) - for pk,_ in db_config_rule_pks: ConfigRuleModel(database, pk).delete() - -def grpc_config_rules_to_raw(grpc_config_rules) -> List[Tuple[ORM_ConfigActionEnum, str, str]]: - def translate(grpc_config_rule): - action = grpc_to_enum__config_action(grpc_config_rule.action) - return action, grpc_config_rule.resource_key, grpc_config_rule.resource_value - return [translate(grpc_config_rule) for grpc_config_rule in grpc_config_rules] - -def get_config_rules( - database : Database, db_parent_pk : str, config_name : str - ) -> List[Tuple[ORM_ConfigActionEnum, str, str]]: - - str_config_key = key_to_str([db_parent_pk, config_name], separator=':') - db_config = get_object(database, ConfigModel, str_config_key, raise_if_not_found=False) - return [] if db_config is None else [ - (ORM_ConfigActionEnum._value2member_map_.get(config_rule['action']), - config_rule['resource_key'], config_rule['resource_value']) - for config_rule in db_config.dump() - ] - -def update_config( - database : Database, db_parent_pk : str, config_name : str, - raw_config_rules : List[Tuple[ORM_ConfigActionEnum, str, str]] - ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]: - - str_config_key = key_to_str([db_parent_pk, config_name], separator=':') - result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key) - db_config, created = result - - db_objects : List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]] = [(db_config, created)] - - for position,(action, resource_key, resource_value) in enumerate(raw_config_rules): - str_rule_key_hash = fast_hasher(resource_key) - str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':') - result : Tuple[ConfigRuleModel, bool] = update_or_create_object( - database, ConfigRuleModel, str_config_rule_key, { - 'config_fk': db_config, 'position': position, 'action': action, 'key': resource_key, - 'value': resource_value}) - db_config_rule, updated = result - db_objects.append((db_config_rule, updated)) - - return db_objects diff --git a/src/device/service/database/ContextModel.py b/src/device/service/database/ContextModel.py deleted file mode 100644 index f4da5097e3f1ab0298ec66ff6007fb6a21be65ed..0000000000000000000000000000000000000000 --- a/src/device/service/database/ContextModel.py +++ /dev/null @@ -1,24 +0,0 @@ -import logging -from typing import Dict, List -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model - -LOGGER = logging.getLogger(__name__) - -class ContextModel(Model): - pk = PrimaryKeyField() - context_uuid = StringField(required=True, allow_empty=False) - -# def dump_id(self) -> Dict: -# return {'context_uuid': {'uuid': self.context_uuid}} - -# def dump_topology_ids(self) -> List[Dict]: -# from .TopologyModel import TopologyModel # pylint: disable=import-outside-toplevel -# db_topology_pks = self.references(TopologyModel) -# return [TopologyModel(self.database, pk).dump_id() for pk,_ in db_topology_pks] - -# def dump(self, include_topologies=True) -> Dict: # pylint: disable=arguments-differ -# result = {'context_id': self.dump_id()} -# if include_topologies: result['topology_ids'] = self.dump_topology_ids() -# return result diff --git a/src/device/service/database/DatabaseTools.py b/src/device/service/database/DatabaseTools.py deleted file mode 100644 index 5b43aae70af054f5d6da0bd92d9f2e59d152dc84..0000000000000000000000000000000000000000 --- a/src/device/service/database/DatabaseTools.py +++ /dev/null @@ -1,110 +0,0 @@ -import grpc -from typing import Any, Dict, Tuple -from common.orm.Database import Database -from common.orm.HighLevel import get_or_create_object, update_or_create_object -from common.orm.backend.Tools import key_to_str -from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException -from context.client.ContextClient import ContextClient -from device.proto.context_pb2 import Device, DeviceId -from device.service.driver_api.FilterFields import FilterFieldEnum -from .ConfigModel import delete_all_config_rules, grpc_config_rules_to_raw, update_config -from .ContextModel import ContextModel -from .DeviceModel import DeviceModel, DriverModel, grpc_to_enum__device_operational_status, set_drivers -from .EndPointModel import EndPointModel -from .TopologyModel import TopologyModel - -def update_device_in_local_database(database : Database, device : Device) -> Tuple[DeviceModel, bool]: - device_uuid = device.device_id.device_uuid.uuid - - for i,endpoint in enumerate(device.device_endpoints): - endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid - if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid - if device_uuid != endpoint_device_uuid: - raise InvalidArgumentException( - 'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid, - ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)]) - - initial_config_result = update_config(database, device_uuid, 'initial', []) - - config_rules = grpc_config_rules_to_raw(device.device_config.config_rules) - delete_all_config_rules(database, device_uuid, 'running') - running_config_result = update_config(database, device_uuid, 'running', config_rules) - - result : Tuple[DeviceModel, bool] = update_or_create_object(database, DeviceModel, device_uuid, { - 'device_uuid' : device_uuid, - 'device_type' : device.device_type, - 'device_operational_status': grpc_to_enum__device_operational_status(device.device_operational_status), - 'device_initial_config_fk' : initial_config_result[0][0], - 'device_running_config_fk' : running_config_result[0][0], - }) - db_device, updated = result - set_drivers(database, db_device, device.device_drivers) - - for i,endpoint in enumerate(device.device_endpoints): - endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid - endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid - if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid - - str_endpoint_key = key_to_str([device_uuid, endpoint_uuid]) - endpoint_attributes = { - 'device_fk' : db_device, - 'endpoint_uuid': endpoint_uuid, - 'endpoint_type': endpoint.endpoint_type, - } - - endpoint_topology_context_uuid = endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid - endpoint_topology_uuid = endpoint.endpoint_id.topology_id.topology_uuid.uuid - if len(endpoint_topology_context_uuid) > 0 and len(endpoint_topology_uuid) > 0: - result : Tuple[ContextModel, bool] = get_or_create_object( - database, ContextModel, endpoint_topology_context_uuid, defaults={ - 'context_uuid': endpoint_topology_context_uuid, - }) - db_context, _ = result - - str_topology_key = key_to_str([endpoint_topology_context_uuid, endpoint_topology_uuid]) - result : Tuple[TopologyModel, bool] = get_or_create_object( - database, TopologyModel, str_topology_key, defaults={ - 'context_fk': db_context, - 'topology_uuid': endpoint_topology_uuid, - }) - db_topology, _ = result - - str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':') - endpoint_attributes['topology_fk'] = db_topology - - result : Tuple[EndPointModel, bool] = update_or_create_object( - database, EndPointModel, str_endpoint_key, endpoint_attributes) - _, db_endpoint_updated = result - updated = updated or db_endpoint_updated - - return db_device, updated - -def sync_device_from_context( - device_uuid : str, context_client : ContextClient, database : Database - ) -> Tuple[DeviceModel, bool]: - - try: - device : Device = context_client.GetDevice(DeviceId(device_uuid={'uuid': device_uuid})) - except grpc.RpcError as e: - if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member - return None - return update_device_in_local_database(database, device) - -def sync_device_to_context(db_device : DeviceModel, context_client : ContextClient) -> None: - if db_device is None: return - context_client.SetDevice(Device(**db_device.dump( - include_config_rules=True, include_drivers=True, include_endpoints=True))) - -def delete_device_from_context(db_device : DeviceModel, context_client : ContextClient) -> None: - if db_device is None: return - context_client.RemoveDevice(DeviceId(**db_device.dump_id())) - -def get_device_driver_filter_fields(db_device : DeviceModel) -> Dict[FilterFieldEnum, Any]: - if db_device is None: return {} - database = db_device.database - db_driver_pks = db_device.references(DriverModel) - db_driver_names = [DriverModel(database, pk).driver.value for pk,_ in db_driver_pks] - return { - FilterFieldEnum.DEVICE_TYPE: db_device.device_type, - FilterFieldEnum.DRIVER : db_driver_names, - } diff --git a/src/device/service/database/DeviceModel.py b/src/device/service/database/DeviceModel.py deleted file mode 100644 index bba19d787622019b7b8f25de9c07b7c0984ec42c..0000000000000000000000000000000000000000 --- a/src/device/service/database/DeviceModel.py +++ /dev/null @@ -1,91 +0,0 @@ -import functools, logging -from enum import Enum -from typing import Dict, List -from common.orm.Database import Database -from common.orm.backend.Tools import key_to_str -from common.orm.fields.EnumeratedField import EnumeratedField -from common.orm.fields.ForeignKeyField import ForeignKeyField -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model -from device.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum -from .ConfigModel import ConfigModel -from .Tools import grpc_to_enum - -LOGGER = logging.getLogger(__name__) - -class ORM_DeviceDriverEnum(Enum): - UNDEFINED = DeviceDriverEnum.DEVICEDRIVER_UNDEFINED - OPENCONFIG = DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG - TRANSPORT_API = DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API - P4 = DeviceDriverEnum.DEVICEDRIVER_P4 - IETF_NETWORK_TOPOLOGY = DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY - ONF_TR_352 = DeviceDriverEnum.DEVICEDRIVER_ONF_TR_352 - -grpc_to_enum__device_driver = functools.partial( - grpc_to_enum, DeviceDriverEnum, ORM_DeviceDriverEnum) - -class ORM_DeviceOperationalStatusEnum(Enum): - UNDEFINED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED - DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED - ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED - -grpc_to_enum__device_operational_status = functools.partial( - grpc_to_enum, DeviceOperationalStatusEnum, ORM_DeviceOperationalStatusEnum) - -class DeviceModel(Model): - pk = PrimaryKeyField() - device_uuid = StringField(required=True, allow_empty=False) - device_type = StringField() - device_initial_config_fk = ForeignKeyField(ConfigModel) - device_running_config_fk = ForeignKeyField(ConfigModel) - device_operational_status = EnumeratedField(ORM_DeviceOperationalStatusEnum, required=True) - - def dump_id(self) -> Dict: - return {'device_uuid': {'uuid': self.device_uuid}} - - def dump_initial_config(self) -> Dict: - return ConfigModel(self.database, self.device_initial_config_fk).dump() - - def dump_running_config(self) -> Dict: - return ConfigModel(self.database, self.device_running_config_fk).dump() - - def dump_drivers(self) -> List[int]: - db_driver_pks = self.references(DriverModel) - return [DriverModel(self.database, pk).dump() for pk,_ in db_driver_pks] - - def dump_endpoints(self) -> List[Dict]: - from .EndPointModel import EndPointModel # pylint: disable=import-outside-toplevel - db_endpoints_pks = self.references(EndPointModel) - return [EndPointModel(self.database, pk).dump() for pk,_ in db_endpoints_pks] - - def dump( # pylint: disable=arguments-differ - self, include_config_rules=True, include_drivers=True, include_endpoints=True - ) -> Dict: - result = { - 'device_id': self.dump_id(), - 'device_type': self.device_type, - 'device_operational_status': self.device_operational_status.value, - } - if include_config_rules: result.setdefault('device_config', {})['config_rules'] = self.dump_running_config() - if include_drivers: result['device_drivers'] = self.dump_drivers() - if include_endpoints: result['device_endpoints'] = self.dump_endpoints() - return result - -class DriverModel(Model): # pylint: disable=abstract-method - pk = PrimaryKeyField() - device_fk = ForeignKeyField(DeviceModel) - driver = EnumeratedField(ORM_DeviceDriverEnum, required=True) - - def dump(self) -> Dict: - return self.driver.value - -def set_drivers(database : Database, db_device : DeviceModel, grpc_device_drivers): - db_device_pk = db_device.pk - for driver in grpc_device_drivers: - orm_driver = grpc_to_enum__device_driver(driver) - str_device_driver_key = key_to_str([db_device_pk, orm_driver.name]) - db_device_driver = DriverModel(database, str_device_driver_key) - db_device_driver.device_fk = db_device - db_device_driver.driver = orm_driver - db_device_driver.save() diff --git a/src/device/service/database/EndPointModel.py b/src/device/service/database/EndPointModel.py deleted file mode 100644 index 38b87d6f37c4e99dd3790f4d8802acd03873f77d..0000000000000000000000000000000000000000 --- a/src/device/service/database/EndPointModel.py +++ /dev/null @@ -1,33 +0,0 @@ -import logging -from typing import Dict -from common.orm.fields.ForeignKeyField import ForeignKeyField -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model -from .DeviceModel import DeviceModel -from .TopologyModel import TopologyModel - -LOGGER = logging.getLogger(__name__) - -class EndPointModel(Model): - pk = PrimaryKeyField() - topology_fk = ForeignKeyField(TopologyModel, required=False) - device_fk = ForeignKeyField(DeviceModel) - endpoint_uuid = StringField(required=True, allow_empty=False) - endpoint_type = StringField() - - def dump_id(self) -> Dict: - device_id = DeviceModel(self.database, self.device_fk).dump_id() - result = { - 'device_id': device_id, - 'endpoint_uuid': {'uuid': self.endpoint_uuid}, - } - if self.topology_fk is not None: - result['topology_id'] = TopologyModel(self.database, self.topology_fk).dump_id() - return result - - def dump(self) -> Dict: - return { - 'endpoint_id': self.dump_id(), - 'endpoint_type': self.endpoint_type, - } diff --git a/src/device/service/database/KpiModel.py b/src/device/service/database/KpiModel.py deleted file mode 100644 index 1bed9fc7a169665eb459b295a6fc9903513e13f0..0000000000000000000000000000000000000000 --- a/src/device/service/database/KpiModel.py +++ /dev/null @@ -1,45 +0,0 @@ -import logging -from typing import Dict -from common.orm.fields.EnumeratedField import EnumeratedField -from common.orm.fields.FloatField import FloatField -from common.orm.fields.ForeignKeyField import ForeignKeyField -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model -from .DeviceModel import DeviceModel -from .EndPointModel import EndPointModel -from .KpiSampleType import ORM_KpiSampleType - -LOGGER = logging.getLogger(__name__) - -class KpiModel(Model): - pk = PrimaryKeyField() - kpi_uuid = StringField(required=True, allow_empty=False) - kpi_description = StringField(required=False, allow_empty=True) - kpi_sample_type = EnumeratedField(ORM_KpiSampleType, required=True) - device_fk = ForeignKeyField(DeviceModel) - endpoint_fk = ForeignKeyField(EndPointModel) - sampling_duration = FloatField(min_value=0, required=True) - sampling_interval = FloatField(min_value=0, required=True) - - def dump_id(self) -> Dict: - return {'kpi_id': {'uuid': self.kpi_uuid}} - - def dump_descriptor(self) -> Dict: - result = { - 'kpi_description': self.kpi_description, - 'kpi_sample_type': self.kpi_sample_type.value, - } - if self.device_fk is not None: - result['device_id'] = DeviceModel(self.database, self.device_fk).dump_id() - if self.endpoint_fk is not None: - result['endpoint_id'] = EndPointModel(self.database, self.endpoint_fk).dump_id() - return result - - def dump(self) -> Dict: - return { - 'kpi_id': self.dump_id(), - 'kpi_descriptor': self.dump_descriptor(), - 'sampling_duration_s': self.sampling_duration, - 'sampling_interval_s': self.sampling_interval, - } diff --git a/src/device/service/database/KpiSampleType.py b/src/device/service/database/KpiSampleType.py deleted file mode 100644 index e5c4c5bbc0407e7dd3650ca4ff2f2e95a1202472..0000000000000000000000000000000000000000 --- a/src/device/service/database/KpiSampleType.py +++ /dev/null @@ -1,14 +0,0 @@ -import functools -from enum import Enum -from device.proto.kpi_sample_types_pb2 import KpiSampleType -from .Tools import grpc_to_enum - -class ORM_KpiSampleType(Enum): - UNKNOWN = KpiSampleType.UNKNOWN - PACKETS_TRANSMITTED = KpiSampleType.PACKETS_TRANSMITTED - PACKETS_RECEIVED = KpiSampleType.PACKETS_RECEIVED - BYTES_TRANSMITTED = KpiSampleType.BYTES_TRANSMITTED - BYTES_RECEIVED = KpiSampleType.BYTES_RECEIVED - -grpc_to_enum__kpi_sample_type = functools.partial( - grpc_to_enum, KpiSampleType, ORM_KpiSampleType) diff --git a/src/device/service/database/Tools.py b/src/device/service/database/Tools.py deleted file mode 100644 index 36ffbcd46fcf686371b0799445ce4f9ce5b75838..0000000000000000000000000000000000000000 --- a/src/device/service/database/Tools.py +++ /dev/null @@ -1,58 +0,0 @@ -import hashlib, re -from enum import Enum -from typing import Dict, List, Tuple, Union - -# Convenient helper function to remove dictionary items in dict/list/set comprehensions. - -def remove_dict_key(dictionary : Dict, key : str): - dictionary.pop(key, None) - return dictionary - -# Enumeration classes are redundant with gRPC classes, but gRPC does not provide a programmatical method to retrieve -# the values it expects from strings containing the desired value symbol or its integer value, so a kind of mapping is -# required. Besides, ORM Models expect Enum classes in EnumeratedFields; we create specific and conveniently defined -# Enum classes to serve both purposes. - -def grpc_to_enum(grpc_enum_class, orm_enum_class : Enum, grpc_enum_value): - grpc_enum_name = grpc_enum_class.Name(grpc_enum_value) - grpc_enum_prefix = orm_enum_class.__name__.upper() - grpc_enum_prefix = re.sub(r'^ORM_(.+)$', r'\1', grpc_enum_prefix) - grpc_enum_prefix = re.sub(r'^(.+)ENUM$', r'\1', grpc_enum_prefix) - grpc_enum_prefix = grpc_enum_prefix + '_' - orm_enum_name = grpc_enum_name.replace(grpc_enum_prefix, '') - orm_enum_value = orm_enum_class._member_map_.get(orm_enum_name) # pylint: disable=protected-access - return orm_enum_value - -# For some models, it is convenient to produce a string hash for fast comparisons of existence or modification. Method -# fast_hasher computes configurable length (between 1 and 64 byte) hashes and retrieves them in hex representation. - -FASTHASHER_ITEM_ACCEPTED_FORMAT = 'Union[bytes, str]' -FASTHASHER_DATA_ACCEPTED_FORMAT = 'Union[{fmt:s}, List[{fmt:s}], Tuple[{fmt:s}]]'.format( - fmt=FASTHASHER_ITEM_ACCEPTED_FORMAT) - -def fast_hasher(data : Union[bytes, str, List[Union[bytes, str]], Tuple[Union[bytes, str]]], digest_size : int = 8): - hasher = hashlib.blake2b(digest_size=digest_size) - # Do not accept sets, dicts, or other unordered dats tructures since their order is arbitrary thus producing - # different hashes depending on the order. Consider adding support for sets or dicts with previous sorting of - # items by their key. - - if isinstance(data, bytes): - data = [data] - elif isinstance(data, str): - data = [data.encode('UTF-8')] - elif isinstance(data, (list, tuple)): - pass - else: - msg = 'data({:s}) must be {:s}, found {:s}' - raise TypeError(msg.format(str(data), FASTHASHER_DATA_ACCEPTED_FORMAT, str(type(data)))) - - for i,item in enumerate(data): - if isinstance(item, str): - item = item.encode('UTF-8') - elif isinstance(item, bytes): - pass - else: - msg = 'data[{:d}]({:s}) must be {:s}, found {:s}' - raise TypeError(msg.format(i, str(item), FASTHASHER_ITEM_ACCEPTED_FORMAT, str(type(item)))) - hasher.update(item) - return hasher.hexdigest() diff --git a/src/device/service/database/TopologyModel.py b/src/device/service/database/TopologyModel.py deleted file mode 100644 index 71c1067f03803c6d89c69910c82a3c1e24970eee..0000000000000000000000000000000000000000 --- a/src/device/service/database/TopologyModel.py +++ /dev/null @@ -1,25 +0,0 @@ -import logging -from typing import Dict -from common.orm.fields.ForeignKeyField import ForeignKeyField -from common.orm.fields.PrimaryKeyField import PrimaryKeyField -from common.orm.fields.StringField import StringField -from common.orm.model.Model import Model -from .ContextModel import ContextModel - -LOGGER = logging.getLogger(__name__) - -class TopologyModel(Model): - pk = PrimaryKeyField() - context_fk = ForeignKeyField(ContextModel) - topology_uuid = StringField(required=True, allow_empty=False) - -# def dump_id(self) -> Dict: -# context_id = ContextModel(self.database, self.context_fk).dump_id() -# return { -# 'context_id': context_id, -# 'topology_uuid': {'uuid': self.topology_uuid}, -# } - -# def dump(self) -> Dict: -# result = {'topology_id': self.dump_id()} -# return result diff --git a/src/device/service/database/__init__.py b/src/device/service/database/__init__.py deleted file mode 100644 index ff9b7da0cd0f83f8e01bbb904d8e2471503f00ca..0000000000000000000000000000000000000000 --- a/src/device/service/database/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# In-Memory database with a simplified representation of Context Database focused on the Device model. -# Used as an internal configuration cache, for message validation, and message formatting purposes. diff --git a/src/device/service/driver_api/DriverFactory.py b/src/device/service/driver_api/DriverFactory.py index 10b4961fcf98871cc4cbf3e078391006591b606c..c226e434c75286d99c2051098e0d18d9cf483caa 100644 --- a/src/device/service/driver_api/DriverFactory.py +++ b/src/device/service/driver_api/DriverFactory.py @@ -1,73 +1,50 @@ -import logging, operator -from enum import Enum -from typing import Any, Dict, Iterable, List, Set, Tuple +from typing import Dict, Set +from device.service.driver_api.QueryFields import QUERY_FIELDS from device.service.driver_api._Driver import _Driver -from device.service.driver_api.Exceptions import ( - UnsatisfiedFilterException, UnsupportedDriverClassException, UnsupportedFilterFieldException, - UnsupportedFilterFieldValueException) -from device.service.driver_api.FilterFields import FILTER_FIELD_ALLOWED_VALUES, FilterFieldEnum - -LOGGER = logging.getLogger(__name__) +from device.service.driver_api.Exceptions import MultipleResultsForQueryException, UnsatisfiedQueryException, \ + UnsupportedDriverClassException, UnsupportedQueryFieldException, UnsupportedQueryFieldValueException class DriverFactory: - def __init__(self, drivers : List[Tuple[type, List[Dict[FilterFieldEnum, Any]]]]) -> None: + def __init__(self) -> None: self.__indices : Dict[str, Dict[str, Set[_Driver]]] = {} # Dict{field_name => Dict{field_value => Set{Driver}}} - for driver_class,filter_field_sets in drivers: - for filter_fields in filter_field_sets: - filter_fields = {k.value:v for k,v in filter_fields.items()} - self.register_driver_class(driver_class, **filter_fields) - - def register_driver_class(self, driver_class, **filter_fields): + def register_driver_class(self, driver_class, **query_fields): if not issubclass(driver_class, _Driver): raise UnsupportedDriverClassException(str(driver_class)) driver_name = driver_class.__name__ - supported_filter_fields = set(FILTER_FIELD_ALLOWED_VALUES.keys()) - unsupported_filter_fields = set(filter_fields.keys()).difference(supported_filter_fields) - if len(unsupported_filter_fields) > 0: - raise UnsupportedFilterFieldException(unsupported_filter_fields, driver_class_name=driver_name) + unsupported_query_fields = set(query_fields.keys()).difference(set(QUERY_FIELDS.keys())) + if len(unsupported_query_fields) > 0: + raise UnsupportedQueryFieldException(unsupported_query_fields, driver_class_name=driver_name) - for field_name, field_values in filter_fields.items(): + for field_name, field_value in query_fields.items(): field_indice = self.__indices.setdefault(field_name, dict()) - field_enum_values = FILTER_FIELD_ALLOWED_VALUES.get(field_name) - if not isinstance(field_values, Iterable) or isinstance(field_values, str): - field_values = [field_values] - for field_value in field_values: - if isinstance(field_value, Enum): field_value = field_value.value - if field_enum_values is not None and field_value not in field_enum_values: - raise UnsupportedFilterFieldValueException( - field_name, field_value, field_enum_values, driver_class_name=driver_name) - field_indice_drivers = field_indice.setdefault(field_value, set()) - field_indice_drivers.add(driver_class) + field_enum_values = QUERY_FIELDS.get(field_name) + if field_enum_values is not None and field_value not in field_enum_values: + raise UnsupportedQueryFieldValueException( + field_name, field_value, field_enum_values, driver_class_name=driver_name) + field_indice_drivers = field_indice.setdefault(field_name, set()) + field_indice_drivers.add(driver_class) + + def get_driver_class(self, **query_fields) -> _Driver: + unsupported_query_fields = set(query_fields.keys()).difference(set(QUERY_FIELDS.keys())) + if len(unsupported_query_fields) > 0: raise UnsupportedQueryFieldException(unsupported_query_fields) - def get_driver_class(self, **filter_fields) -> _Driver: - supported_filter_fields = set(FILTER_FIELD_ALLOWED_VALUES.keys()) - unsupported_filter_fields = set(filter_fields.keys()).difference(supported_filter_fields) - if len(unsupported_filter_fields) > 0: raise UnsupportedFilterFieldException(unsupported_filter_fields) + candidate_driver_classes = None - candidate_driver_classes : Dict[_Driver, int] = None # number of filter hits per driver - for field_name, field_values in filter_fields.items(): + for field_name, field_value in query_fields.items(): field_indice = self.__indices.get(field_name) if field_indice is None: continue - field_enum_values = FILTER_FIELD_ALLOWED_VALUES.get(field_name) - if not isinstance(field_values, Iterable) or isinstance(field_values, str): - field_values = [field_values] - - field_candidate_driver_classes = set() - for field_value in field_values: - if field_enum_values is not None and field_value not in field_enum_values: - raise UnsupportedFilterFieldValueException(field_name, field_value, field_enum_values) - field_indice_drivers = field_indice.get(field_value) - if field_indice_drivers is None: continue - field_candidate_driver_classes = field_candidate_driver_classes.union(field_indice_drivers) - - if candidate_driver_classes is None: - candidate_driver_classes = {k:1 for k in field_candidate_driver_classes} - else: - for candidate_driver_class in candidate_driver_classes: - if candidate_driver_class not in field_candidate_driver_classes: continue - candidate_driver_classes[candidate_driver_class] += 1 - - if len(candidate_driver_classes) == 0: raise UnsatisfiedFilterException(filter_fields) - candidate_driver_classes = sorted(candidate_driver_classes.items(), key=operator.itemgetter(1), reverse=True) - return candidate_driver_classes[0][0] + field_enum_values = QUERY_FIELDS.get(field_name) + if field_enum_values is not None and field_value not in field_enum_values: + raise UnsupportedQueryFieldValueException(field_name, field_value, field_enum_values) + field_indice_drivers = field_indice.get(field_name) + if field_indice_drivers is None: continue + + candidate_driver_classes = set().union(field_indice_drivers) if candidate_driver_classes is None else \ + candidate_driver_classes.intersection(field_indice_drivers) + + if len(candidate_driver_classes) == 0: raise UnsatisfiedQueryException(query_fields) + if len(candidate_driver_classes) > 1: + # TODO: Consider choosing driver with more query fields being satisfied (i.e., the most restrictive one) + raise MultipleResultsForQueryException(query_fields, {d.__name__ for d in candidate_driver_classes}) + return candidate_driver_classes.pop() diff --git a/src/device/service/driver_api/DriverInstanceCache.py b/src/device/service/driver_api/DriverInstanceCache.py deleted file mode 100644 index f960e37cbd22a7d4c06c9119ffaf64540dfc791a..0000000000000000000000000000000000000000 --- a/src/device/service/driver_api/DriverInstanceCache.py +++ /dev/null @@ -1,57 +0,0 @@ -import logging, threading -from typing import Any, Dict, Optional - -from device.service.driver_api.FilterFields import FilterFieldEnum -from ._Driver import _Driver -from .DriverFactory import DriverFactory -from .Exceptions import DriverInstanceCacheTerminatedException - -LOGGER = logging.getLogger(__name__) - -class DriverInstanceCache: - def __init__(self, driver_factory : DriverFactory) -> None: - self._lock = threading.Lock() - self._terminate = threading.Event() - self._device_uuid__to__driver_instance : Dict[str, _Driver] = {} - self._driver_factory = driver_factory - - def get( - self, device_uuid : str, filter_fields : Dict[FilterFieldEnum, Any] = {}, address : Optional[str] = None, - port : Optional[int] = None, settings : Dict[str, Any] = {}) -> _Driver: - - if self._terminate.is_set(): - raise DriverInstanceCacheTerminatedException() - - filter_fields = {k.value:v for k,v in filter_fields.items()} - - with self._lock: - driver_instance = self._device_uuid__to__driver_instance.get(device_uuid) - if driver_instance is not None: return driver_instance - - if len(filter_fields) == 0: return None - MSG = 'Selecting driver for device({:s}) with filter_fields({:s})...' - LOGGER.info(MSG.format(str(device_uuid), str(filter_fields))) - driver_class = self._driver_factory.get_driver_class(**filter_fields) - MSG = 'Driver({:s}) selected for device({:s}) with filter_fields({:s})...' - LOGGER.info(MSG.format(str(driver_class.__name__), str(device_uuid), str(filter_fields))) - driver_instance : _Driver = driver_class(address, port, **settings) - self._device_uuid__to__driver_instance[device_uuid] = driver_instance - return driver_instance - - def delete(self, device_uuid : str) -> None: - with self._lock: - device_driver = self._device_uuid__to__driver_instance.pop(device_uuid, None) - if device_driver is None: return - device_driver.Disconnect() - - def terminate(self) -> None: - self._terminate.set() - with self._lock: - while len(self._device_uuid__to__driver_instance) > 0: - try: - device_uuid,device_driver = self._device_uuid__to__driver_instance.popitem() - device_driver.Disconnect() - except: # pylint: disable=bare-except - msg = 'Error disconnecting Driver({:s}) from device. Will retry later...' - LOGGER.exception(msg.format(device_uuid)) - self._device_uuid__to__driver_instance[device_uuid] = device_driver diff --git a/src/device/service/driver_api/Exceptions.py b/src/device/service/driver_api/Exceptions.py index c35d6372d60b4ea465b40d98e9e43e979835451d..2275bb04cbf9334a6823544bc48e8ad345d2dc20 100644 --- a/src/device/service/driver_api/Exceptions.py +++ b/src/device/service/driver_api/Exceptions.py @@ -1,54 +1,30 @@ -class UnsatisfiedFilterException(Exception): - def __init__(self, filter_fields): - msg = 'No Driver satisfies FilterFields({:s})' - super().__init__(msg.format(str(filter_fields))) +class MultipleResultsForQueryException(Exception): + def __init__(self, query_fields, driver_names): + super().__init__('Multiple Drivers({}) satisfy QueryFields({})'.format(str(driver_names), str(query_fields))) + +class UnsatisfiedQueryException(Exception): + def __init__(self, query_fields): + super().__init__('No Driver satisfies QueryFields({})'.format(str(query_fields))) class UnsupportedDriverClassException(Exception): def __init__(self, driver_class_name): - msg = 'Class({:s}) is not a subclass of _Driver' - super().__init__(msg.format(str(driver_class_name))) + super().__init__('Class({}) is not a subclass of _Driver'.format(str(driver_class_name))) -class UnsupportedFilterFieldException(Exception): - def __init__(self, unsupported_filter_fields, driver_class_name=None): +class UnsupportedQueryFieldException(Exception): + def __init__(self, unsupported_query_fields, driver_class_name=None): if driver_class_name: - msg = 'FilterFields({:s}) specified by Driver({:s}) are not supported' - msg = msg.format(str(unsupported_filter_fields), str(driver_class_name)) + msg = 'QueryFields({}) specified by Driver({}) are not supported'.format( + str(unsupported_query_fields), str(driver_class_name)) else: - msg = 'FilterFields({:s}) specified in Filter are not supported' - msg = msg.format(str(unsupported_filter_fields)) + msg = 'QueryFields({}) specified in query are not supported'.format(str(unsupported_query_fields)) super().__init__(msg) -class UnsupportedFilterFieldValueException(Exception): - def __init__(self, filter_field_name, filter_field_value, allowed_filter_field_values, driver_class_name=None): +class UnsupportedQueryFieldValueException(Exception): + def __init__(self, query_field_name, query_field_value, allowed_query_field_values, driver_class_name=None): if driver_class_name: - msg = 'FilterField({:s}={:s}) specified by Driver({:s}) is not supported. Allowed values are {:s}' - msg = msg.format( - str(filter_field_name), str(filter_field_value), str(driver_class_name), - str(allowed_filter_field_values)) + msg = 'QueryField({}={}) specified by Driver({}) is not supported. Allowed values are {}'.format( + str(query_field_name), str(query_field_value), str(driver_class_name), str(allowed_query_field_values)) else: - msg = 'FilterField({:s}={:s}) specified in Filter is not supported. Allowed values are {:s}' - msg = msg.format(str(filter_field_name), str(filter_field_value), str(allowed_filter_field_values)) - super().__init__(msg) - -class DriverInstanceCacheTerminatedException(Exception): - def __init__(self): - msg = 'DriverInstanceCache is terminated. No new instances can be processed.' - super().__init__(msg) - -class UnsupportedResourceKeyException(Exception): - def __init__(self, resource_key): - msg = 'ResourceKey({:s}) not supported' - msg = msg.format(str(resource_key)) - super().__init__(msg) - -class ConfigFieldNotFoundException(Exception): - def __init__(self, config_field_name): - msg = 'ConfigField({:s}) not specified in resource' - msg = msg.format(str(config_field_name)) - super().__init__(msg) - -class ConfigFieldsNotSupportedException(Exception): - def __init__(self, config_fields): - msg = 'ConfigFields({:s}) not supported in resource' - msg = msg.format(str(config_fields)) + msg = 'QueryField({}={}) specified in query is not supported. Allowed values are {}'.format( + str(query_field_name), str(query_field_value), str(allowed_query_field_values)) super().__init__(msg) diff --git a/src/device/service/driver_api/FilterFields.py b/src/device/service/driver_api/FilterFields.py deleted file mode 100644 index c7de05f92a743c826d54897930b10013bd09c2b7..0000000000000000000000000000000000000000 --- a/src/device/service/driver_api/FilterFields.py +++ /dev/null @@ -1,26 +0,0 @@ -from enum import Enum -from device.service.database.DeviceModel import ORM_DeviceDriverEnum - -class DeviceTypeFilterFieldEnum(Enum): - EMULATED = 'emulated' - OPTICAL_ROADM = 'optical-roadm' - OPTICAL_TRANDPONDER = 'optical-trandponder' - OPTICAL_LINE_SYSTEM = 'optical-line-system' - PACKET_ROUTER = 'packet-router' - PACKET_SWITCH = 'packet-switch' - -class FilterFieldEnum(Enum): - DEVICE_TYPE = 'device_type' - DRIVER = 'driver' - VENDOR = 'vendor' - MODEL = 'model' - SERIAL_NUMBER = 'serial_number' - -# Map allowed filter fields to allowed values per Filter field. If no restriction (free text) None is specified -FILTER_FIELD_ALLOWED_VALUES = { - FilterFieldEnum.DEVICE_TYPE.value : {i.value for i in DeviceTypeFilterFieldEnum}, - FilterFieldEnum.DRIVER.value : {i.value for i in ORM_DeviceDriverEnum}, - FilterFieldEnum.VENDOR.value : None, - FilterFieldEnum.MODEL.value : None, - FilterFieldEnum.SERIAL_NUMBER.value : None, -} diff --git a/src/device/service/driver_api/QueryFields.py b/src/device/service/driver_api/QueryFields.py new file mode 100644 index 0000000000000000000000000000000000000000..15b3f5b7582283083c9ea1080dc4f3d6f5390501 --- /dev/null +++ b/src/device/service/driver_api/QueryFields.py @@ -0,0 +1,33 @@ +from enum import Enum + +class DeviceTypeQueryFieldEnum(Enum): + OPTICAL_ROADM = 'optical-roadm' + OPTICAL_TRANDPONDER = 'optical-trandponder' + PACKET_ROUTER = 'packet-router' + PACKET_SWITCH = 'packet-switch' + +class ProtocolQueryFieldEnum(Enum): + SOFTWARE = 'software' + GRPC = 'grpc' + RESTAPI = 'restapi' + NETCONF = 'netconf' + GNMI = 'gnmi' + RESTCONF = 'restconf' + +class DataModelQueryFieldEnum(Enum): + EMULATED = 'emu' + OPENCONFIG = 'oc' + P4 = 'p4' + TRANSPORT_API = 'tapi' + IETF_NETWORK_TOPOLOGY = 'ietf-netw-topo' + ONF_TR_352 = 'onf-tr-352' + +# Map allowed query fields to allowed values per query field. If no restriction (free text) None is specified +QUERY_FIELDS = { + 'device_type' : {i.value for i in DeviceTypeQueryFieldEnum}, + 'protocol' : {i.value for i in ProtocolQueryFieldEnum}, + 'data_model' : {i.value for i in DataModelQueryFieldEnum}, + 'vendor' : None, + 'model' : None, + 'serial_number': None, +} diff --git a/src/device/service/driver_api/Tools.py b/src/device/service/driver_api/Tools.py deleted file mode 100644 index ab22cbc040daee7e47e80b0235b79b19cdb7acbc..0000000000000000000000000000000000000000 --- a/src/device/service/driver_api/Tools.py +++ /dev/null @@ -1,57 +0,0 @@ -import operator -from typing import Any, Callable, List, Tuple, Union - -ACTION_MSG_GET = 'Get resource(key={:s})' -ACTION_MSG_SET = 'Set resource(key={:s}, value={:s})' -ACTION_MSG_DELETE = 'Delete resource(key={:s}, value={:s})' -ACTION_MSG_SUBSCRIBE = 'Subscribe subscription(key={:s}, duration={:s}, interval={:s})' -ACTION_MSG_UNSUBSCRIBE = 'Unsubscribe subscription(key={:s}, duration={:s}, interval={:s})' - -def _get(resource_key : str): - return ACTION_MSG_GET.format(str(resource_key)) - -def _set(resource : Tuple[str, Any]): - return ACTION_MSG_SET.format(*tuple(map(str, resource))) - -def _delete(resource : Tuple[str, Any]): - return ACTION_MSG_SET.format(*tuple(map(str, resource))) - -def _subscribe(subscription : Tuple[str, float, float]): - return ACTION_MSG_SUBSCRIBE.format(*tuple(map(str, subscription))) - -def _unsubscribe(subscription : Tuple[str, float, float]): - return ACTION_MSG_UNSUBSCRIBE.format(*tuple(map(str, subscription))) - -def _check_errors( - error_func : Callable, parameters_list : List[Any], results_list : List[Union[bool, Exception]] - ) -> List[str]: - errors = [] - for parameters, results in zip(parameters_list, results_list): - if not isinstance(results, Exception): continue - errors.append('Unable to {:s}; error({:s})'.format(error_func(parameters), str(results))) - return errors - -def check_get_errors( - resource_keys : List[str], results : List[Tuple[str, Union[Any, None, Exception]]] - ) -> List[str]: - return _check_errors(_get, resource_keys, map(operator.itemgetter(1), results)) - -def check_set_errors( - resources : List[Tuple[str, Any]], results : List[Union[bool, Exception]] - ) -> List[str]: - return _check_errors(_set, resources, results) - -def check_delete_errors( - resources : List[Tuple[str, Any]], results : List[Union[bool, Exception]] - ) -> List[str]: - return _check_errors(_delete, resources, results) - -def check_subscribe_errors( - subscriptions : List[Tuple[str, float, float]], results : List[Union[bool, Exception]] - ) -> List[str]: - return _check_errors(_subscribe, subscriptions, results) - -def check_unsubscribe_errors( - subscriptions : List[Tuple[str, float, float]], results : List[Union[bool, Exception]] - ) -> List[str]: - return _check_errors(_unsubscribe, subscriptions, results) diff --git a/src/device/service/driver_api/_Driver.py b/src/device/service/driver_api/_Driver.py index 73174ba53ac6e0b357d3bd790c53f429bea36d87..69ac93cb6a071a40aca25b28f930e390bfbfe6b0 100644 --- a/src/device/service/driver_api/_Driver.py +++ b/src/device/service/driver_api/_Driver.py @@ -1,21 +1,15 @@ from typing import Any, Iterator, List, Tuple, Union -# Special resource names to request to the driver to retrieve the specified configuration/structural resources. -# These resource names should be used with GetConfig() method. -RESOURCE_ENDPOINTS = '__endpoints__' -RESOURCE_INTERFACES = '__interfaces__' -RESOURCE_NETWORK_INSTANCES = '__network_instances__' - class _Driver: - def __init__(self, address : str, port : int, **settings) -> None: + def __init__(self, address : str, port : int, **kwargs) -> None: """ Initialize Driver. Parameters: address : str The address of the device port : int The port of the device - **settings - Extra settings required by the driver. + **kwargs + Extra attributes can be configured using kwargs. """ raise NotImplementedError() @@ -35,38 +29,20 @@ class _Driver: """ raise NotImplementedError() - def GetInitialConfig(self) -> List[Tuple[str, Any]]: - """ Retrieve initial configuration of entire device. - Returns: - values : List[Tuple[str, Any]] - List of tuples (resource key, resource value) for resource keys. - """ - raise NotImplementedError() - - def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: + def GetConfig(self, resource_keys : List[str]) -> List[Union[Any, None, Exception]]: """ Retrieve running configuration of entire device, or selected resource keys. Parameters: resource_keys : List[str] List of keys pointing to the resources to be retrieved. Returns: - values : List[Tuple[str, Union[Any, None, Exception]]] - List of tuples (resource key, resource value) for resource keys requested. If a resource is found, - the appropriate value type must be retrieved. If a resource is not found, None must be retrieved as - value for that resource. In case of Exception, the Exception must be retrieved as value. + values : List[Union[Any, None, Exception]] + List of values for resource keys requested. Return values must be in the same order than resource + keys requested. If a resource is found, the appropriate value type must be retrieved, if a resource + is not found, None must be retrieved in the List for that resource. In case of Exception processing + a resource, the Exception must be retrieved. """ raise NotImplementedError() - #def GetResource(self, endpoint_uuid : str) -> Optional[str]: - # """ Retrieve the endpoint path for subscriptions. - # Parameters: - # endpoint_uuid : str - # Target endpoint UUID - # Returns: - # resource_path : Optional[str] - # The path of the endpoint, or None if it is not found. - # """ - # raise NotImplementedError() - def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: """ Create/Update configuration for a list of resources. Parameters: @@ -81,12 +57,11 @@ class _Driver: """ raise NotImplementedError() - def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: - """ Delete configuration for a list of resources. + def DeleteConfig(self, resource_keys : List[str]) -> List[Union[bool, Exception]]: + """ Delete configuration for a list of resource keys. Parameters: - resources : List[Tuple[str, Any]] - List of tuples, each containing a resource_key pointing the resource to be modified, and a - resource_value containing possible additionally required values to locate the value to be removed. + resource_keys : List[str] + List of keys pointing to the resources to be deleted. Returns: results : List[bool] List of results for resource key deletions requested. Return values must be in the same order than diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py index e59bae207e4cd14f238aabcb7e373bb973374005..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/device/service/drivers/__init__.py +++ b/src/device/service/drivers/__init__.py @@ -1,25 +0,0 @@ -from ..driver_api.FilterFields import FilterFieldEnum, DeviceTypeFilterFieldEnum, ORM_DeviceDriverEnum -from .emulated.EmulatedDriver import EmulatedDriver -from .openconfig.OpenConfigDriver import OpenConfigDriver -from .transport_api.TransportApiDriver import TransportApiDriver - -DRIVERS = [ - (EmulatedDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeFilterFieldEnum.EMULATED, - FilterFieldEnum.DRIVER : ORM_DeviceDriverEnum.UNDEFINED, - } - ]), - (OpenConfigDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeFilterFieldEnum.PACKET_ROUTER, - FilterFieldEnum.DRIVER : ORM_DeviceDriverEnum.OPENCONFIG, - } - ]), - (TransportApiDriver, [ - { - FilterFieldEnum.DEVICE_TYPE: DeviceTypeFilterFieldEnum.OPTICAL_LINE_SYSTEM, - FilterFieldEnum.DRIVER : ORM_DeviceDriverEnum.TRANSPORT_API, - } - ]), -] diff --git a/src/device/service/driver_api/AnyTreeTools.py b/src/device/service/drivers/emulated/AnyTreeTools.py similarity index 98% rename from src/device/service/driver_api/AnyTreeTools.py rename to src/device/service/drivers/emulated/AnyTreeTools.py index df61c7e030a13a3d0d758ce51a011aaa95deb49f..e7817b78921e3b91fb84ca660f022c869ac88220 100644 --- a/src/device/service/driver_api/AnyTreeTools.py +++ b/src/device/service/drivers/emulated/AnyTreeTools.py @@ -1,6 +1,8 @@ import anytree from typing import Any, List, Optional +from anytree.render import Row + class TreeNode(anytree.node.Node): def __init__(self, name, parent=None, children=None, **kwargs) -> None: super().__init__(name, parent=parent, children=children, **kwargs) diff --git a/src/device/service/drivers/emulated/EmulatedDriver.py b/src/device/service/drivers/emulated/EmulatedDriver.py index 06dc4bd7c36e99d5f081f97e2caa46b8bb5fd2d6..7dc5757f7afb928bd56e64b5a87d4c414171cd6b 100644 --- a/src/device/service/drivers/emulated/EmulatedDriver.py +++ b/src/device/service/drivers/emulated/EmulatedDriver.py @@ -1,25 +1,23 @@ import anytree, logging, pytz, queue, random, threading from datetime import datetime, timedelta -from typing import Any, Iterator, List, Optional, Tuple, Union +from typing import Any, Iterator, List, Tuple, Union from apscheduler.executors.pool import ThreadPoolExecutor from apscheduler.job import Job from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.schedulers.background import BackgroundScheduler -from common.type_checkers.Checkers import chk_float, chk_length, chk_string, chk_type +from common.Checkers import chk_float, chk_length, chk_string, chk_type from device.service.driver_api._Driver import _Driver -from device.service.driver_api.AnyTreeTools import TreeNode, dump_subtree, get_subnode, set_subnode_value +from .AnyTreeTools import TreeNode, dump_subtree, get_subnode, set_subnode_value LOGGER = logging.getLogger(__name__) -def do_sampling(resource_key : str, out_samples : queue.Queue): +def sample(resource_key : str, out_samples : queue.Queue): out_samples.put_nowait((datetime.timestamp(datetime.utcnow()), resource_key, random.random())) class EmulatedDriver(_Driver): - def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called + def __init__(self, address : str, port : int, **kwargs) -> None: self.__lock = threading.Lock() - self.__initial = TreeNode('.') - self.__running = TreeNode('.') - self.__started = threading.Event() + self.__root = TreeNode('.') self.__terminate = threading.Event() self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events self.__scheduler.configure( @@ -30,35 +28,21 @@ class EmulatedDriver(_Driver): self.__out_samples = queue.Queue() def Connect(self) -> bool: - # If started, assume it is already connected - if self.__started.is_set(): return True - # Connect triggers activation of sampling events that will be scheduled based on subscriptions self.__scheduler.start() - - # Indicate the driver is now connected to the device - self.__started.set() return True def Disconnect(self) -> bool: # Trigger termination of loops and processes self.__terminate.set() - - # If not started, assume it is already disconnected - if not self.__started.is_set(): return True - # Disconnect triggers deactivation of sampling events self.__scheduler.shutdown() return True - def GetInitialConfig(self) -> List[Tuple[str, Any]]: - with self.__lock: - return dump_subtree(self.__initial) - - def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: + def GetConfig(self, resource_keys : List[str] = []) -> List[Union[Any, None, Exception]]: chk_type('resources', resource_keys, list) with self.__lock: - if len(resource_keys) == 0: return dump_subtree(self.__running) + if len(resource_keys) == 0: return dump_subtree(self.__root) results = [] resolver = anytree.Resolver(pathattr='name') for i,resource_key in enumerate(resource_keys): @@ -66,23 +50,16 @@ class EmulatedDriver(_Driver): try: chk_string(str_resource_name, resource_key, allow_empty=False) resource_path = resource_key.split('/') - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception validating {:s}: {:s}'.format(str_resource_name, str(resource_key))) - results.append((resource_key, e)) # if validation fails, store the exception + except Exception as e: + LOGGER.exception('Exception validating {}: {}'.format(str_resource_name, str(resource_key))) + results.append(e) # if validation fails, store the exception continue - resource_node = get_subnode(resolver, self.__running, resource_path, default=None) + resource_node = get_subnode(resolver, self.__root, resource_path, default=None) # if not found, resource_node is None - if resource_node is None: continue - results.extend(dump_subtree(resource_node)) + results.append(None if resource_node is None else dump_subtree(resource_node)) return results - def GetResource(self, endpoint_uuid : str) -> Optional[str]: - chk_string('endpoint_uuid', endpoint_uuid) - return { - #'key': 'value', - }.get(endpoint_uuid) - def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] @@ -93,39 +70,35 @@ class EmulatedDriver(_Driver): str_resource_name = 'resources[#{:d}]'.format(i) try: chk_type(str_resource_name, resource, (list, tuple)) - chk_length(str_resource_name, resource, min_length=2, max_length=2) + chk_length(str_resource_name, resource, allowed_lengths=2) resource_key,resource_value = resource - chk_string(str_resource_name, resource_key, allow_empty=False) resource_path = resource_key.split('/') - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception validating {:s}: {:s}'.format(str_resource_name, str(resource_key))) + except Exception as e: + LOGGER.exception('Exception validating {}: {}'.format(str_resource_name, str(resource_key))) results.append(e) # if validation fails, store the exception continue - set_subnode_value(resolver, self.__running, resource_path, resource_value) + set_subnode_value(resolver, self.__root, resource_path, resource_value) results.append(True) return results - def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: - chk_type('resources', resources, list) - if len(resources) == 0: return [] + def DeleteConfig(self, resource_keys : List[str]) -> List[Union[bool, Exception]]: + chk_type('resources', resource_keys, list) + if len(resource_keys) == 0: return [] results = [] resolver = anytree.Resolver(pathattr='name') with self.__lock: - for i,resource in enumerate(resources): - str_resource_name = 'resources[#{:d}]'.format(i) + for i,resource_key in enumerate(resource_keys): + str_resource_name = 'resource_key[#{:d}]'.format(i) try: - chk_type(str_resource_name, resource, (list, tuple)) - chk_length(str_resource_name, resource, min_length=2, max_length=2) - resource_key,_ = resource chk_string(str_resource_name, resource_key, allow_empty=False) resource_path = resource_key.split('/') - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception validating {:s}: {:s}'.format(str_resource_name, str(resource_key))) + except Exception as e: + LOGGER.exception('Exception validating {}: {}'.format(str_resource_name, str(resource_key))) results.append(e) # if validation fails, store the exception continue - resource_node = get_subnode(resolver, self.__running, resource_path, default=None) + resource_node = get_subnode(resolver, self.__root, resource_path, default=None) # if not found, resource_node is None if resource_node is None: results.append(False) @@ -138,24 +111,24 @@ class EmulatedDriver(_Driver): results.append(True) return results - def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: - chk_type('subscriptions', subscriptions, list) - if len(subscriptions) == 0: return [] + def SubscribeState(self, resources : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: + chk_type('resources', resources, list) + if len(resources) == 0: return [] results = [] resolver = anytree.Resolver(pathattr='name') with self.__lock: - for i,subscription in enumerate(subscriptions): - str_subscription_name = 'subscriptions[#{:d}]'.format(i) + for i,resource in enumerate(resources): + str_resource_name = 'resources[#{:d}]'.format(i) try: - chk_type(str_subscription_name, subscription, (list, tuple)) - chk_length(str_subscription_name, subscription, min_length=3, max_length=3) - resource_key,sampling_duration,sampling_interval = subscription - chk_string(str_subscription_name + '.resource_key', resource_key, allow_empty=False) + chk_type(str_resource_name, resource, (list, tuple)) + chk_length(str_resource_name, resource, allowed_lengths=3) + resource_key,sampling_duration,sampling_interval = resource + chk_string(str_resource_name + '.resource_key', resource_key, allow_empty=False) resource_path = resource_key.split('/') - chk_float(str_subscription_name + '.sampling_duration', sampling_duration, min_value=0) - chk_float(str_subscription_name + '.sampling_interval', sampling_interval, min_value=0) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception validating {:s}: {:s}'.format(str_subscription_name, str(resource_key))) + chk_float(str_resource_name + '.sampling_duration', sampling_duration, min_value=0) + chk_float(str_resource_name + '.sampling_interval', sampling_interval, min_value=0) + except Exception as e: + LOGGER.exception('Exception validating {}: {}'.format(str_resource_name, str(resource_key))) results.append(e) # if validation fails, store the exception continue @@ -166,39 +139,39 @@ class EmulatedDriver(_Driver): job_id = 'k={:s}/d={:f}/i={:f}'.format(resource_key, sampling_duration, sampling_interval) job = self.__scheduler.add_job( - do_sampling, args=(resource_key, self.__out_samples), kwargs={}, + sample, args=(resource_key, self.__out_samples), kwargs={}, id=job_id, trigger='interval', seconds=sampling_interval, start_date=start_date, end_date=end_date, timezone=pytz.utc) subscription_path = resource_path + ['{:.3f}:{:.3f}'.format(sampling_duration, sampling_interval)] - set_subnode_value(resolver, self.__running, subscription_path, job) + set_subnode_value(resolver, self.__root, subscription_path, job) results.append(True) return results - def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: - chk_type('subscriptions', subscriptions, list) - if len(subscriptions) == 0: return [] + def UnsubscribeState(self, resources : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: + chk_type('resources', resources, list) + if len(resources) == 0: return [] results = [] resolver = anytree.Resolver(pathattr='name') with self.__lock: - for i,resource in enumerate(subscriptions): - str_subscription_name = 'resources[#{:d}]'.format(i) + for i,resource in enumerate(resources): + str_resource_name = 'resources[#{:d}]'.format(i) try: - chk_type(str_subscription_name, resource, (list, tuple)) - chk_length(str_subscription_name, resource, min_length=3, max_length=3) + chk_type(str_resource_name, resource, (list, tuple)) + chk_length(str_resource_name, resource, allowed_lengths=3) resource_key,sampling_duration,sampling_interval = resource - chk_string(str_subscription_name + '.resource_key', resource_key, allow_empty=False) + chk_string(str_resource_name + '.resource_key', resource_key, allow_empty=False) resource_path = resource_key.split('/') - chk_float(str_subscription_name + '.sampling_duration', sampling_duration, min_value=0) - chk_float(str_subscription_name + '.sampling_interval', sampling_interval, min_value=0) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception validating {:s}: {:s}'.format(str_subscription_name, str(resource_key))) + chk_float(str_resource_name + '.sampling_duration', sampling_duration, min_value=0) + chk_float(str_resource_name + '.sampling_interval', sampling_interval, min_value=0) + except Exception as e: + LOGGER.exception('Exception validating {}: {}'.format(str_resource_name, str(resource_key))) results.append(e) # if validation fails, store the exception continue subscription_path = resource_path + ['{:.3f}:{:.3f}'.format(sampling_duration, sampling_interval)] - subscription_node = get_subnode(resolver, self.__running, subscription_path) - + subscription_node = get_subnode(resolver, self.__root, subscription_path) + # if not found, resource_node is None if subscription_node is None: results.append(False) @@ -206,7 +179,7 @@ class EmulatedDriver(_Driver): job : Job = getattr(subscription_node, 'value', None) if job is None or not isinstance(job, Job): - raise Exception('Malformed subscription node or wrong resource key: {:s}'.format(str(resource))) + raise Exception('Malformed subscription node or wrong resource key: {}'.format(str(resource))) job.remove() parent = subscription_node.parent diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py deleted file mode 100644 index e2381d81e5e1aa81907f90b6e473efb154e92e79..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/OpenConfigDriver.py +++ /dev/null @@ -1,231 +0,0 @@ -import logging, pytz, queue, threading -#from datetime import datetime, timedelta -from typing import Any, List, Tuple, Union -#from apscheduler.executors.pool import ThreadPoolExecutor -#from apscheduler.job import Job -#from apscheduler.jobstores.memory import MemoryJobStore -#from apscheduler.schedulers.background import BackgroundScheduler -from netconf_client.connect import connect_ssh -from netconf_client.ncclient import Manager -from common.type_checkers.Checkers import chk_length, chk_string, chk_type -from device.service.driver_api.Exceptions import UnsupportedResourceKeyException -from device.service.driver_api._Driver import _Driver -from device.service.driver_api.AnyTreeTools import set_subnode_value -from device.service.drivers.openconfig.Tools import xml_pretty_print, xml_to_dict, xml_to_file -from device.service.drivers.openconfig.templates import ALL_RESOURCE_KEYS, compose_config, get_filter, parse - -#logging.getLogger('ncclient.transport.ssh').setLevel(logging.WARNING) - -LOGGER = logging.getLogger(__name__) - -#def do_sampling(resource_key : str, out_samples : queue.Queue): -# out_samples.put_nowait((datetime.timestamp(datetime.utcnow()), resource_key, random.random())) - -class OpenConfigDriver(_Driver): - def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called - self.__address = address - self.__port = int(port) - self.__settings = settings - self.__lock = threading.Lock() - #self.__initial = TreeNode('.') - #self.__running = TreeNode('.') - self.__started = threading.Event() - self.__terminate = threading.Event() - self.__netconf_manager : Manager = None - #self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events - #self.__scheduler.configure( - # jobstores = {'default': MemoryJobStore()}, - # executors = {'default': ThreadPoolExecutor(max_workers=1)}, - # job_defaults = {'coalesce': False, 'max_instances': 3}, - # timezone=pytz.utc) - #self.__out_samples = queue.Queue() - - def Connect(self) -> bool: - with self.__lock: - if self.__started.is_set(): return True - username = self.__settings.get('username') - password = self.__settings.get('password') - timeout = int(self.__settings.get('timeout', 120)) - session = connect_ssh( - host=self.__address, port=self.__port, username=username, password=password) - self.__netconf_manager = Manager(session, timeout=timeout) - self.__netconf_manager.set_logger_level(logging.DEBUG) - # Connect triggers activation of sampling events that will be scheduled based on subscriptions - #self.__scheduler.start() - self.__started.set() - return True - - def Disconnect(self) -> bool: - with self.__lock: - # Trigger termination of loops and processes - self.__terminate.set() - # If not started, assume it is already disconnected - if not self.__started.is_set(): return True - # Disconnect triggers deactivation of sampling events - #self.__scheduler.shutdown() - self.__netconf_manager.close_session() - return True - - def GetInitialConfig(self) -> List[Tuple[str, Any]]: - with self.__lock: - return [] - - def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: - chk_type('resources', resource_keys, list) - results = [] - with self.__lock: - if len(resource_keys) == 0: resource_keys = ALL_RESOURCE_KEYS - for i,resource_key in enumerate(resource_keys): - str_resource_name = 'resource_key[#{:d}]'.format(i) - try: - chk_string(str_resource_name, resource_key, allow_empty=False) - str_filter = get_filter(resource_key) - if str_filter is None: str_filter = resource_key - xml_data = self.__netconf_manager.get(filter=str_filter).data_ele - if isinstance(xml_data, Exception): raise xml_data - results.extend(parse(resource_key, xml_data)) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception retrieving {:s}: {:s}'.format(str_resource_name, str(resource_key))) - results.append((resource_key, e)) # if validation fails, store the exception - return results - - #def GetResource(self, endpoint_uuid : str) -> Optional[str]: - # chk_string('endpoint_uuid', endpoint_uuid) - # return { - # #'key': 'value', - # }.get(endpoint_uuid) - - def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: - chk_type('resources', resources, list) - if len(resources) == 0: return [] - results = [] - with self.__lock: - for i,resource in enumerate(resources): - str_resource_name = 'resources[#{:d}]'.format(i) - try: - #LOGGER.info('resource = {:s}'.format(str(resource))) - chk_type(str_resource_name, resource, (list, tuple)) - chk_length(str_resource_name, resource, min_length=2, max_length=2) - resource_key,resource_value = resource - chk_string(str_resource_name + '.key', resource_key, allow_empty=False) - str_config_message = compose_config(resource_key, resource_value) - if str_config_message is None: raise UnsupportedResourceKeyException(resource_key) - #LOGGER.info('str_config_message = {:s}'.format(str(str_config_message))) - self.__netconf_manager.edit_config(str_config_message, target='running') - results.append(True) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception setting {:s}: {:s}'.format(str_resource_name, str(resource))) - results.append(e) # if validation fails, store the exception - return results - - def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: - chk_type('resources', resources, list) - if len(resources) == 0: return [] - results = [] - with self.__lock: - for i,resource in enumerate(resources): - str_resource_name = 'resources[#{:d}]'.format(i) - try: - #LOGGER.info('resource = {:s}'.format(str(resource))) - chk_type(str_resource_name, resource, (list, tuple)) - chk_length(str_resource_name, resource, min_length=2, max_length=2) - resource_key,resource_value = resource - chk_string(str_resource_name + '.key', resource_key, allow_empty=False) - str_config_message = compose_config(resource_key, resource_value, delete=True) - if str_config_message is None: raise UnsupportedResourceKeyException(resource_key) - #LOGGER.info('str_config_message = {:s}'.format(str(str_config_message))) - self.__netconf_manager.edit_config(str_config_message, target='running') - results.append(True) - except Exception as e: # pylint: disable=broad-except - LOGGER.exception('Exception deleting {:s}: {:s}'.format(str_resource_name, str(resource_key))) - results.append(e) # if validation fails, store the exception - return results - -# def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: -# chk_type('subscriptions', subscriptions, list) -# if len(subscriptions) == 0: return [] -# results = [] -# resolver = anytree.Resolver(pathattr='name') -# with self.__lock: -# for i,subscription in enumerate(subscriptions): -# str_subscription_name = 'subscriptions[#{:d}]'.format(i) -# try: -# chk_type(str_subscription_name, subscription, (list, tuple)) -# chk_length(str_subscription_name, subscription, min_length=3, max_length=3) -# resource_key,sampling_duration,sampling_interval = subscription -# chk_string(str_subscription_name + '.resource_key', resource_key, allow_empty=False) -# resource_path = resource_key.split('/') -# chk_float(str_subscription_name + '.sampling_duration', sampling_duration, min_value=0) -# chk_float(str_subscription_name + '.sampling_interval', sampling_interval, min_value=0) -# except Exception as e: # pylint: disable=broad-except -# LOGGER.exception('Exception validating {:s}: {:s}'.format(str_subscription_name, str(resource_key))) -# results.append(e) # if validation fails, store the exception -# continue -# -# start_date,end_date = None,None -# if sampling_duration <= 1.e-12: -# start_date = datetime.utcnow() -# end_date = start_date + timedelta(seconds=sampling_duration) -# -# job_id = 'k={:s}/d={:f}/i={:f}'.format(resource_key, sampling_duration, sampling_interval) -# job = self.__scheduler.add_job( -# do_sampling, args=(resource_key, self.__out_samples), kwargs={}, -# id=job_id, trigger='interval', seconds=sampling_interval, -# start_date=start_date, end_date=end_date, timezone=pytz.utc) -# -# subscription_path = resource_path + ['{:.3f}:{:.3f}'.format(sampling_duration, sampling_interval)] -# set_subnode_value(resolver, self.__running, subscription_path, job) -# results.append(True) -# return results -# -# def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: -# chk_type('subscriptions', subscriptions, list) -# if len(subscriptions) == 0: return [] -# results = [] -# resolver = anytree.Resolver(pathattr='name') -# with self.__lock: -# for i,resource in enumerate(subscriptions): -# str_subscription_name = 'resources[#{:d}]'.format(i) -# try: -# chk_type(str_subscription_name, resource, (list, tuple)) -# chk_length(str_subscription_name, resource, min_length=3, max_length=3) -# resource_key,sampling_duration,sampling_interval = resource -# chk_string(str_subscription_name + '.resource_key', resource_key, allow_empty=False) -# resource_path = resource_key.split('/') -# chk_float(str_subscription_name + '.sampling_duration', sampling_duration, min_value=0) -# chk_float(str_subscription_name + '.sampling_interval', sampling_interval, min_value=0) -# except Exception as e: # pylint: disable=broad-except -# LOGGER.exception('Exception validating {:s}: {:s}'.format(str_subscription_name, str(resource_key))) -# results.append(e) # if validation fails, store the exception -# continue -# -# subscription_path = resource_path + ['{:.3f}:{:.3f}'.format(sampling_duration, sampling_interval)] -# subscription_node = get_subnode(resolver, self.__running, subscription_path) -# -# # if not found, resource_node is None -# if subscription_node is None: -# results.append(False) -# continue -# -# job : Job = getattr(subscription_node, 'value', None) -# if job is None or not isinstance(job, Job): -# raise Exception('Malformed subscription node or wrong resource key: {:s}'.format(str(resource))) -# job.remove() -# -# parent = subscription_node.parent -# children = list(parent.children) -# children.remove(subscription_node) -# parent.children = tuple(children) -# -# results.append(True) -# return results -# -# def GetState(self, blocking=False) -> Iterator[Tuple[str, Any]]: -# while not self.__terminate.is_set(): -# try: -# sample = self.__out_samples.get(block=blocking, timeout=0.1) -# except queue.Empty: -# if blocking: continue -# return -# if sample is None: continue -# yield sample diff --git a/src/device/service/drivers/openconfig/Tools.py b/src/device/service/drivers/openconfig/Tools.py deleted file mode 100644 index 230a6e3c33586c5d1771a6da2fd9dabc533e9538..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/Tools.py +++ /dev/null @@ -1,11 +0,0 @@ -import xml.dom.minidom, xmltodict - -def xml_pretty_print(data : str): - return xml.dom.minidom.parseString(data).toprettyxml() - -def xml_to_file(data : str, file_path : str) -> None: - with open(file_path, mode='w', encoding='UTF-8') as f: - f.write(xml_pretty_print(data)) - -def xml_to_dict(data : str): - return xmltodict.parse(data) diff --git a/src/device/service/drivers/openconfig/templates/EndPoints.py b/src/device/service/drivers/openconfig/templates/EndPoints.py deleted file mode 100644 index 4908c818374ca3b94fb77c5d5cd88d97d3c881b5..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/EndPoints.py +++ /dev/null @@ -1,27 +0,0 @@ -import logging, lxml.etree as ET -from typing import Any, Dict, List, Tuple -from .Namespace import NAMESPACES -from .Tools import add_value_from_tag - -LOGGER = logging.getLogger(__name__) - -XPATH_PORTS = "//ocp:components/ocp:component/ocp:state[ocp:type='PORT']/.." - -def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]: - response = [] - for xml_component in xml_data.xpath(XPATH_PORTS, namespaces=NAMESPACES): - #LOGGER.info('xml_component = {:s}'.format(str(ET.tostring(xml_component)))) - - endpoint = {} - - component_name = xml_component.find('ocp:name', namespaces=NAMESPACES) - if component_name is None or component_name.text is None: continue - add_value_from_tag(endpoint, 'name', component_name) - - component_type = xml_component.find( - 'ocpp:port/ocpp:breakout-mode/ocpp:state/ocpp:channel-speed', namespaces=NAMESPACES) - add_value_from_tag(endpoint, 'type', component_type) - - if len(endpoint) == 0: continue - response.append(('endpoint[{:s}]'.format(endpoint['name']), endpoint)) - return response diff --git a/src/device/service/drivers/openconfig/templates/Interfaces.py b/src/device/service/drivers/openconfig/templates/Interfaces.py deleted file mode 100644 index 0bbd70d04a3c093dcdbad4966be3030dbc8ba0fb..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/Interfaces.py +++ /dev/null @@ -1,65 +0,0 @@ -import logging, lxml.etree as ET -from typing import Any, Dict, List, Tuple -from .Namespace import NAMESPACES -from .Tools import add_value_from_collection, add_value_from_tag - -LOGGER = logging.getLogger(__name__) - -XPATH_INTERFACES = "//oci:interfaces/oci:interface" -XPATH_SUBINTERFACES = ".//oci:subinterfaces/oci:subinterface" -XPATH_IPV4ADDRESSES = ".//ociip:ipv4/ociip:addresses/ociip:address" - -def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]: - response = [] - for xml_interface in xml_data.xpath(XPATH_INTERFACES, namespaces=NAMESPACES): - LOGGER.info('xml_interface = {:s}'.format(str(ET.tostring(xml_interface)))) - - interface = {} - - interface_name = xml_interface.find('oci:name', namespaces=NAMESPACES) - if interface_name is None or interface_name.text is None: continue - add_value_from_tag(interface, 'name', interface_name) - - interface_type = xml_interface.find('oci:config/oci:type', namespaces=NAMESPACES) - add_value_from_tag(interface, 'type', interface_type) - - for xml_subinterface in xml_interface.xpath(XPATH_SUBINTERFACES, namespaces=NAMESPACES): - LOGGER.info('xml_subinterface = {:s}'.format(str(ET.tostring(xml_subinterface)))) - - subinterface = {} - - subinterface_index = xml_subinterface.find('oci:index', namespaces=NAMESPACES) - if subinterface_index is None or subinterface_index.text is None: continue - add_value_from_tag(subinterface, 'index', subinterface_index) - - vlan_id = xml_subinterface.find('ocv:vlan/ocv:config/ocv:vlan-id', namespaces=NAMESPACES) - add_value_from_tag(subinterface, 'vlan_id', vlan_id, cast=int) - - ipv4_addresses = [] - for xml_ipv4_address in xml_subinterface.xpath(XPATH_IPV4ADDRESSES, namespaces=NAMESPACES): - LOGGER.info('xml_ipv4_address = {:s}'.format(str(ET.tostring(xml_ipv4_address)))) - - ipv4_address = {} - - origin = xml_ipv4_address.find('ociip:state/ociip:origin', namespaces=NAMESPACES) - add_value_from_tag(ipv4_address, 'origin', origin) - - address = xml_ipv4_address.find('ociip:state/ociip:ip', namespaces=NAMESPACES) - add_value_from_tag(ipv4_address, 'ip', address) - - prefix = xml_ipv4_address.find('ociip:state/ociip:prefix-length', namespaces=NAMESPACES) - add_value_from_tag(ipv4_address, 'prefix_length', prefix) - - if len(ipv4_address) == 0: continue - ipv4_addresses.append(ipv4_address) - - add_value_from_collection(subinterface, 'ipv4_addresses', ipv4_addresses) - - if len(subinterface) == 0: continue - resource_key = 'interface[{:s}]/subinterface[{:s}]'.format(interface['name'], subinterface['index']) - response.append((resource_key, subinterface)) - - if len(interface) == 0: continue - response.append(('interface[{:s}]'.format(interface['name']), interface)) - - return response diff --git a/src/device/service/drivers/openconfig/templates/Namespace.py b/src/device/service/drivers/openconfig/templates/Namespace.py deleted file mode 100644 index ff4b7c9c747b4efa872ba177e6e6a4fd7f6203b4..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/Namespace.py +++ /dev/null @@ -1,23 +0,0 @@ - -NAMESPACE_NETCONF = 'urn:ietf:params:xml:ns:netconf:base:1.0' - -NAMESPACE_INTERFACES = 'http://openconfig.net/yang/interfaces' -NAMESPACE_INTERFACES_IP = 'http://openconfig.net/yang/interfaces/ip' -NAMESPACE_NETWORK_INSTANCE = 'http://openconfig.net/yang/network-instance' -NAMESPACE_NETWORK_INSTANCE_TYPES = 'http://openconfig.net/yang/network-instance-types' -NAMESPACE_OPENCONFIG_TYPES = 'http://openconfig.net/yang/openconfig-types' -NAMESPACE_PLATFORM = 'http://openconfig.net/yang/platform' -NAMESPACE_PLATFORM_PORT = 'http://openconfig.net/yang/platform/port' -NAMESPACE_VLAN = 'http://openconfig.net/yang/vlan' - -NAMESPACES = { - 'nc' : NAMESPACE_NETCONF, - 'oci' : NAMESPACE_INTERFACES, - 'ociip': NAMESPACE_INTERFACES_IP, - 'ocni' : NAMESPACE_NETWORK_INSTANCE, - 'ocnit': NAMESPACE_NETWORK_INSTANCE_TYPES, - 'ococt': NAMESPACE_OPENCONFIG_TYPES, - 'ocp' : NAMESPACE_PLATFORM, - 'ocpp' : NAMESPACE_PLATFORM_PORT, - 'ocv' : NAMESPACE_VLAN, -} diff --git a/src/device/service/drivers/openconfig/templates/NetworkInstances.py b/src/device/service/drivers/openconfig/templates/NetworkInstances.py deleted file mode 100644 index 06bf5cd0f38aaf8c61f2919c25891e15f9ac4343..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/NetworkInstances.py +++ /dev/null @@ -1,35 +0,0 @@ -import logging, lxml.etree as ET -from typing import Any, Dict, List, Tuple -from .Namespace import NAMESPACES -from .Tools import add_value_from_collection, add_value_from_tag - -LOGGER = logging.getLogger(__name__) - -XPATH_NETWORK_INSTANCES = "//ocni:network-instances/ocni:network-instance" - -def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]: - response = [] - for xml_network_instance in xml_data.xpath(XPATH_NETWORK_INSTANCES, namespaces=NAMESPACES): - #LOGGER.info('xml_network_instance = {:s}'.format(str(ET.tostring(xml_network_instance)))) - - network_instance = {} - - ni_name = xml_network_instance.find('ocni:name', namespaces=NAMESPACES) - if ni_name is None or ni_name.text is None: continue - add_value_from_tag(network_instance, 'name', ni_name) - - ni_type = xml_network_instance.find('ocni:config/ocni:type', namespaces=NAMESPACES) - add_value_from_tag(network_instance, 'type', ni_type) - - ni_router_id = xml_network_instance.find('ocni:config/ocni:router-id', namespaces=NAMESPACES) - add_value_from_tag(network_instance, 'router_id', ni_router_id) - - ni_route_dist = xml_network_instance.find('ocni:config/ocni:route-distinguisher', namespaces=NAMESPACES) - add_value_from_tag(network_instance, 'route_distinguisher', ni_route_dist) - - ni_address_families = [] - add_value_from_collection(network_instance, 'address_families', ni_address_families) - - if len(network_instance) == 0: continue - response.append(('network_instance[{:s}]'.format(network_instance['name']), network_instance)) - return response diff --git a/src/device/service/drivers/openconfig/templates/Tools.py b/src/device/service/drivers/openconfig/templates/Tools.py deleted file mode 100644 index e95167dc56dfd323b6fe88a716573a4246305df0..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/Tools.py +++ /dev/null @@ -1,12 +0,0 @@ -import lxml.etree as ET -from typing import Collection, Dict - -def add_value_from_tag(target : Dict, field_name: str, field_value : ET.Element, cast=None) -> None: - if field_value is None or field_value.text is None: return - field_value = field_value.text - if cast is not None: field_value = cast(field_value) - target[field_name] = field_value - -def add_value_from_collection(target : Dict, field_name: str, field_value : Collection) -> None: - if field_value is None or len(field_value) == 0: return - target[field_name] = field_value diff --git a/src/device/service/drivers/openconfig/templates/__init__.py b/src/device/service/drivers/openconfig/templates/__init__.py deleted file mode 100644 index c1d1450568ac6e7efc7265b434de8f6ebabd61bc..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/__init__.py +++ /dev/null @@ -1,47 +0,0 @@ -import json, logging, lxml.etree as ET, re -from typing import Any, Dict -from jinja2 import Environment, PackageLoader, select_autoescape -from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES -from .EndPoints import parse as parse_endpoints -from .Interfaces import parse as parse_interfaces -from .NetworkInstances import parse as parse_network_instances - -ALL_RESOURCE_KEYS = [ - RESOURCE_ENDPOINTS, - RESOURCE_INTERFACES, - RESOURCE_NETWORK_INSTANCES, -] - -RESOURCE_KEY_MAPPINGS = { - RESOURCE_ENDPOINTS : 'component', - RESOURCE_INTERFACES : 'interface', - RESOURCE_NETWORK_INSTANCES: 'network_instance', -} - -RESOURCE_PARSERS = { - 'component' : parse_endpoints, - 'interface' : parse_interfaces, - 'network_instance': parse_network_instances, -} - -LOGGER = logging.getLogger(__name__) -RE_REMOVE_FILTERS = re.compile(r'\[[^\]]+\]') -JINJA_ENV = Environment(loader=PackageLoader('device.service.drivers.openconfig'), autoescape=select_autoescape()) - -def get_filter(resource_key : str): - resource_key = RESOURCE_KEY_MAPPINGS.get(resource_key, resource_key) - template_name = '{:s}/get.xml'.format(RE_REMOVE_FILTERS.sub('', resource_key)) - template = JINJA_ENV.get_template(template_name) - return '{:s}'.format(template.render()) - -def parse(resource_key : str, xml_data : ET.Element): - parser = RESOURCE_PARSERS.get(RESOURCE_KEY_MAPPINGS.get(resource_key, resource_key)) - if parser is None: return [(resource_key, xml_data)] - return parser(xml_data) - -def compose_config(resource_key : str, resource_value : str, delete : bool = False) -> str: - template_name = '{:s}/edit_config.xml'.format(RE_REMOVE_FILTERS.sub('', resource_key)) - template = JINJA_ENV.get_template(template_name) - data : Dict[str, Any] = json.loads(resource_value) - operation = 'delete' if delete else 'merge' - return '{:s}'.format(template.render(**data, operation=operation)) diff --git a/src/device/service/drivers/openconfig/templates/component/get.xml b/src/device/service/drivers/openconfig/templates/component/get.xml deleted file mode 100644 index aa25ed1e3b11e0c324b361eb52d064dac87a64c5..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/component/get.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml b/src/device/service/drivers/openconfig/templates/interface/edit_config.xml deleted file mode 100644 index ae29586a607b8ffd25e61c0aa9056109aacd3cb9..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - {{name}} - {% if operation is not defined or operation != 'delete' %} - - {{name}} - {{description}} - {{mtu}} - - {% endif %} - - diff --git a/src/device/service/drivers/openconfig/templates/interface/get.xml b/src/device/service/drivers/openconfig/templates/interface/get.xml deleted file mode 100644 index c0867655bd325ee9c3cdd74077ac905e36808d5f..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/interface/get.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml b/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml deleted file mode 100644 index bdc698eeffd626076f6f62e576fe6ef916361412..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/interface/subinterface/edit_config.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - {{name}} - {% if operation is not defined or operation != 'delete' %} - - {{name}} - {{description}} - {{mtu}} - - {% endif %} - - - {{index}} - {% if operation is not defined or operation != 'delete' %} - - {{index}} - - {% endif %} - - - - diff --git a/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml deleted file mode 100644 index fab1fdc61f0b6add9c915e914f830270d9875a0a..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - {{name}} - {% if operation is not defined or operation != 'delete' %} - - {{name}} - oc-ni-types:{{type}} - {% for address_family in address_families %} - oc-types:{{address_family}} - {% endfor %} - {{router_id}} - {{route_distinguisher}} - - {% endif %} - - diff --git a/src/device/service/drivers/openconfig/templates/network_instance/get.xml b/src/device/service/drivers/openconfig/templates/network_instance/get.xml deleted file mode 100644 index 9a439926a782cae27cc6aea347454215492ba323..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/network_instance/get.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml deleted file mode 100644 index 51f2d4318fbdd2d6da120851a72a6edafe173c73..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/openconfig/templates/network_instance/interface/edit_config.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - {{name}} - - - {{id}} - {% if operation is not defined or operation != 'delete' %} - - {{id}} - {{id}} - - {% endif %} - - - - diff --git a/src/device/service/drivers/transport_api/TransportApiDriver.py b/src/device/service/drivers/transport_api/TransportApiDriver.py deleted file mode 100644 index f20173dd022a517d1e5630dc23c3455b0ed3c710..0000000000000000000000000000000000000000 --- a/src/device/service/drivers/transport_api/TransportApiDriver.py +++ /dev/null @@ -1,9 +0,0 @@ -import logging -from device.service.driver_api._Driver import _Driver - -LOGGER = logging.getLogger(__name__) - -# TODO: Implement TransportAPI Driver - -class TransportApiDriver(_Driver): - pass diff --git a/src/device/service/drivers/transport_api/__init__.py b/src/device/service/drivers/transport_api/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/device/tests/.gitignore b/src/device/tests/.gitignore deleted file mode 100644 index 067c7b77db596a97883a03426735b6ede9c6fa48..0000000000000000000000000000000000000000 --- a/src/device/tests/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc. -Device_OpenConfig_Infinera.py diff --git a/src/device/tests/CommonObjects.py b/src/device/tests/CommonObjects.py deleted file mode 100644 index 2b51dcd2322e70dff9a5229e65e6a220708a834f..0000000000000000000000000000000000000000 --- a/src/device/tests/CommonObjects.py +++ /dev/null @@ -1,21 +0,0 @@ -from copy import deepcopy -from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID - -# use "deepcopy" to prevent propagating forced changes during tests - -CONTEXT_ID = {'context_uuid': {'uuid': DEFAULT_CONTEXT_UUID}} -CONTEXT = { - 'context_id': deepcopy(CONTEXT_ID), - 'topology_ids': [], - 'service_ids': [], -} - -TOPOLOGY_ID = { - 'context_id': deepcopy(CONTEXT_ID), - 'topology_uuid': {'uuid': DEFAULT_TOPOLOGY_UUID}, -} -TOPOLOGY = { - 'topology_id': deepcopy(TOPOLOGY_ID), - 'device_ids': [], - 'link_ids': [], -} diff --git a/src/device/tests/Device_Emulated.py b/src/device/tests/Device_Emulated.py deleted file mode 100644 index 155383b49fd12d780e901db1aa2614a55d4e5e14..0000000000000000000000000000000000000000 --- a/src/device/tests/Device_Emulated.py +++ /dev/null @@ -1,47 +0,0 @@ -from copy import deepcopy -from device.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum -from .Tools import config_rule_set, config_rule_delete - -# use "deepcopy" to prevent propagating forced changes during tests - -DEVICE_EMU_UUID = 'EMULARED' -DEVICE_EMU_TYPE = 'emulated' -DEVICE_EMU_ADDRESS = '127.0.0.1' -DEVICE_EMU_PORT = '0' -DEVICE_EMU_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_UNDEFINED] - -DEVICE_EMU_ID = {'device_uuid': {'uuid': DEVICE_EMU_UUID}} -DEVICE_EMU = { - 'device_id': deepcopy(DEVICE_EMU_ID), - 'device_type': DEVICE_EMU_TYPE, - 'device_config': {'config_rules': []}, - 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED, - 'device_drivers': DEVICE_EMU_DRIVERS, - 'device_endpoints': [], -} - -DEVICE_EMU_CONNECT_RULES = [ - config_rule_set('_connect/address', DEVICE_EMU_ADDRESS ), - config_rule_set('_connect/port', DEVICE_EMU_PORT ), -] - -DEVICE_EMU_CONFIG_RULES = [ - config_rule_set('dev/rsrc1/value', 'value1'), - config_rule_set('dev/rsrc2/value', 'value2'), - config_rule_set('dev/rsrc3/value', 'value3'), -] - -DEVICE_EMU_RECONFIG_RULES = [ - config_rule_delete('dev/rsrc1/value', ''), - config_rule_set ('dev/rsrc10/value', 'value10'), - config_rule_set ('dev/rsrc11/value', 'value11'), - config_rule_set ('dev/rsrc12/value', 'value12'), -] - -DEVICE_EMU_DECONFIG_RULES = [ - config_rule_delete('dev/rsrc2/value', 'value2'), - config_rule_delete('dev/rsrc3/value', 'value3'), - config_rule_delete('dev/rsrc10/value', 'value10'), - config_rule_delete('dev/rsrc11/value', 'value11'), - config_rule_delete('dev/rsrc12/value', 'value12'), -] diff --git a/src/device/tests/Device_OpenConfig_Template.py b/src/device/tests/Device_OpenConfig_Template.py deleted file mode 100644 index 73b6d4f55e8ffb08eb4c2e0badf8aa8d012c0d2b..0000000000000000000000000000000000000000 --- a/src/device/tests/Device_OpenConfig_Template.py +++ /dev/null @@ -1,34 +0,0 @@ -from copy import deepcopy -from device.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum -from .Tools import config_rule_set, config_rule_delete - -# use "deepcopy" to prevent propagating forced changes during tests - -DEVICE_OC_UUID = 'DEV2' -DEVICE_OC_TYPE = 'packet-router' -DEVICE_OC_ADDRESS = '127.0.0.1' # populate the Netconf Server IP address of the device to test -DEVICE_OC_PORT = '830' # populate the Netconf Server port of the device to test -DEVICE_OC_USERNAME = 'username' # populate the Netconf Server username of the device to test -DEVICE_OC_PASSWORD = 'password' # populate the Netconf Server password of the device to test -DEVICE_OC_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG] - -DEVICE_OC_ID = {'device_uuid': {'uuid': DEVICE_OC_UUID}} -DEVICE_OC = { - 'device_id': deepcopy(DEVICE_OC_ID), - 'device_type': DEVICE_OC_TYPE, - 'device_config': {'config_rules': []}, - 'device_operational_status': DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED, - 'device_drivers': DEVICE_OC_DRIVERS, - 'device_endpoints': [], # populated through the driver, leave this list empty -} - -DEVICE_OC_CONNECT_RULES = [ - config_rule_set('_connect/address', DEVICE_OC_ADDRESS ), - config_rule_set('_connect/port', DEVICE_OC_PORT ), - config_rule_set('_connect/username', DEVICE_OC_USERNAME), - config_rule_set('_connect/password', DEVICE_OC_PASSWORD), -] - -DEVICE_OC_CONFIG_RULES = [] # populate your configuration rules to test - -DEVICE_OC_DECONFIG_RULES = [] # populate your deconfiguration rules to test diff --git a/src/device/tests/Tools.py b/src/device/tests/Tools.py deleted file mode 100644 index 94a6d50900eb1865c69064b2e98bca0d6e91643b..0000000000000000000000000000000000000000 --- a/src/device/tests/Tools.py +++ /dev/null @@ -1,21 +0,0 @@ -import json -from copy import deepcopy -from typing import Any, Dict, Union -from device.proto.context_pb2 import ConfigActionEnum - -def config_rule(action : ConfigActionEnum, resource_key : str, resource_value : Union[str, Dict[str, Any]]): - if not isinstance(resource_value, str): resource_value = json.dumps(resource_value, sort_keys=True) - return {'action': action, 'resource_key': resource_key, 'resource_value': resource_value} - -def config_rule_set(resource_key : str, resource_value : Union[str, Dict[str, Any]]): - return config_rule(ConfigActionEnum.CONFIGACTION_SET, resource_key, resource_value) - -def config_rule_delete(resource_key : str, resource_value : Union[str, Dict[str, Any]]): - return config_rule(ConfigActionEnum.CONFIGACTION_DELETE, resource_key, resource_value) - -def endpoint_id(topology_id, device_id, endpoint_uuid): - return {'topology_id': deepcopy(topology_id), 'device_id': deepcopy(device_id), - 'endpoint_uuid': {'uuid': endpoint_uuid}} - -def endpoint(topology_id, device_id, endpoint_uuid, endpoint_type): - return {'endpoint_id': endpoint_id(topology_id, device_id, endpoint_uuid), 'endpoint_type': endpoint_type} diff --git a/src/device/tests/test_unitary.py b/src/device/tests/test_unitary.py deleted file mode 100644 index fc9175620b7763cabc9da58756054fda9092490d..0000000000000000000000000000000000000000 --- a/src/device/tests/test_unitary.py +++ /dev/null @@ -1,394 +0,0 @@ -import copy, grpc, logging, operator, os, pytest -from typing import Tuple -from google.protobuf.json_format import MessageToDict -from common.orm.Database import Database -from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum -from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum -from common.message_broker.MessageBroker import MessageBroker -from context.Config import ( - GRPC_SERVICE_PORT as CONTEXT_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as CONTEXT_GRPC_MAX_WORKERS, - GRPC_GRACE_PERIOD as CONTEXT_GRPC_GRACE_PERIOD) -from context.client.ContextClient import ContextClient -from context.proto.context_pb2 import DeviceId -from context.service.grpc_server.ContextService import ContextService -from device.Config import ( - GRPC_SERVICE_PORT as DEVICE_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as DEVICE_GRPC_MAX_WORKERS, - GRPC_GRACE_PERIOD as DEVICE_GRPC_GRACE_PERIOD) -from device.client.DeviceClient import DeviceClient -from device.proto.context_pb2 import ConfigActionEnum, Context, Device, Topology -from device.service.DeviceService import DeviceService -#from device.service.MonitoringLoops import MonitoringLoops -from device.service.driver_api._Driver import _Driver -from device.service.driver_api.DriverFactory import DriverFactory -from device.service.driver_api.DriverInstanceCache import DriverInstanceCache -from device.service.drivers import DRIVERS -#from monitoring.client.monitoring_client import MonitoringClient -from .CommonObjects import CONTEXT, TOPOLOGY -from .Device_Emulated import ( - DEVICE_EMU, DEVICE_EMU_CONFIG_RULES, DEVICE_EMU_CONNECT_RULES, DEVICE_EMU_DECONFIG_RULES, DEVICE_EMU_ID, - DEVICE_EMU_RECONFIG_RULES, DEVICE_EMU_UUID) -try: - from .Device_OpenConfig_Infinera import( - DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID, - DEVICE_OC_UUID) - ENABLE_OPENCONFIG = True -except ImportError: - ENABLE_OPENCONFIG = False - # Create a Device_OpenConfig_??.py file with the details for your device to test it and import it as follows in the - # try block of this import statement. - # from .Device_OpenConfig_?? import( - # DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID, - # DEVICE_OC_UUID) - -LOGGER = logging.getLogger(__name__) -LOGGER.setLevel(logging.DEBUG) - -CONTEXT_GRPC_SERVICE_PORT = 10000 + CONTEXT_GRPC_SERVICE_PORT # avoid privileged ports -DEVICE_GRPC_SERVICE_PORT = 10000 + DEVICE_GRPC_SERVICE_PORT # avoid privileged ports - -DEFAULT_REDIS_SERVICE_HOST = '127.0.0.1' -DEFAULT_REDIS_SERVICE_PORT = 6379 -DEFAULT_REDIS_DATABASE_ID = 0 - -REDIS_CONFIG = { - 'REDIS_SERVICE_HOST': os.environ.get('REDIS_SERVICE_HOST', DEFAULT_REDIS_SERVICE_HOST), - 'REDIS_SERVICE_PORT': os.environ.get('REDIS_SERVICE_PORT', DEFAULT_REDIS_SERVICE_PORT), - 'REDIS_DATABASE_ID' : os.environ.get('REDIS_DATABASE_ID', DEFAULT_REDIS_DATABASE_ID ), -} - -SCENARIOS = [ - ('all_inmemory', DatabaseBackendEnum.INMEMORY, {}, MessageBrokerBackendEnum.INMEMORY, {} ), - #('all_redis', DatabaseBackendEnum.REDIS, REDIS_CONFIG, MessageBrokerBackendEnum.REDIS, REDIS_CONFIG), -] - -@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS) -def context_db_mb(request) -> Tuple[Database, MessageBroker]: - name,db_backend,db_settings,mb_backend,mb_settings = request.param - msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...' - LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings))) - _database = Database(get_database_backend(backend=db_backend, **db_settings)) - _message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings)) - yield _database, _message_broker - _message_broker.terminate() - -@pytest.fixture(scope='session') -def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name - _service = ContextService( - context_db_mb[0], context_db_mb[1], port=CONTEXT_GRPC_SERVICE_PORT, max_workers=CONTEXT_GRPC_MAX_WORKERS, - grace_period=CONTEXT_GRPC_GRACE_PERIOD) - _service.start() - yield _service - _service.stop() - -@pytest.fixture(scope='session') -def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name - _client = ContextClient(address='127.0.0.1', port=CONTEXT_GRPC_SERVICE_PORT) - yield _client - _client.close() - -@pytest.fixture(scope='session') -def device_service(context_client : ContextClient): # pylint: disable=redefined-outer-name - _driver_factory = DriverFactory(DRIVERS) - _driver_instance_cache = DriverInstanceCache(_driver_factory) - #_monitoring_loops = MonitoringLoops(None) # TODO: replace by monitoring client - #_monitoring_loops.start() - _service = DeviceService( - context_client, _driver_instance_cache, - #_monitoring_loops, - port=DEVICE_GRPC_SERVICE_PORT, max_workers=DEVICE_GRPC_MAX_WORKERS, grace_period=DEVICE_GRPC_GRACE_PERIOD) - _service.start() - yield _service - #_monitoring_loops.stop() - _service.stop() - -@pytest.fixture(scope='session') -def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name - _client = DeviceClient(address='127.0.0.1', port=DEVICE_GRPC_SERVICE_PORT) - yield _client - _client.close() - -def grpc_message_to_json_string(message): - return str(MessageToDict( - message, including_default_value_fields=True, preserving_proto_field_name=True, use_integers_for_enums=False)) - - -def test_prepare_environment( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - context_client.SetContext(Context(**CONTEXT)) - context_client.SetTopology(Topology(**TOPOLOGY)) - - -# ----- Test Device Driver Emulated ------------------------------------------------------------------------------------ - -def test_device_emulated_add_error_cases( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - with pytest.raises(grpc.RpcError) as e: - DEVICE_EMU_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_EMU) - DEVICE_EMU_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONNECT_RULES) - DEVICE_EMU_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_RULES) - device_client.AddDevice(Device(**DEVICE_EMU_WITH_EXTRA_RULES)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg_head = 'device.device_config.config_rules([' - msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\ - 'with "_connect/" tag. Others should be configured after adding the device.' - except_msg = str(e.value.details()) - assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail) - - -def test_device_emulated_add_correct( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - DEVICE_EMU_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_EMU) - DEVICE_EMU_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONNECT_RULES) - device_client.AddDevice(Device(**DEVICE_EMU_WITH_CONNECT_RULES)) - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now - assert driver is not None - - -def test_device_emulated_get( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_EMU_ID)) - LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config))) - - device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID)) - LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data))) - - -def test_device_emulated_configure( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now - assert driver is not None - - driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - assert len(driver_config) == 0 - - DEVICE_EMU_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_EMU) - DEVICE_EMU_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_RULES) - device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_CONFIG_RULES)) - - driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - assert len(driver_config) == 3 - assert driver_config[0] == ('/dev/rsrc1/value', 'value1') - assert driver_config[1] == ('/dev/rsrc2/value', 'value2') - assert driver_config[2] == ('/dev/rsrc3/value', 'value3') - - device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID)) - config_rules = [ - (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value) - for config_rule in device_data.device_config.config_rules - ] - LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format( - '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules]))) - for config_rule in DEVICE_EMU_CONFIG_RULES: - config_rule = ( - ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value']) - assert config_rule in config_rules - - # Try to reconfigure... - - DEVICE_EMU_WITH_RECONFIG_RULES = copy.deepcopy(DEVICE_EMU) - DEVICE_EMU_WITH_RECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_RECONFIG_RULES) - device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_RECONFIG_RULES)) - - driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - assert len(driver_config) == 5 - assert driver_config[0] == ('/dev/rsrc10/value', 'value10') - assert driver_config[1] == ('/dev/rsrc11/value', 'value11') - assert driver_config[2] == ('/dev/rsrc12/value', 'value12') - assert driver_config[3] == ('/dev/rsrc2/value', 'value2') - assert driver_config[4] == ('/dev/rsrc3/value', 'value3') - - device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID)) - config_rules = [ - (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value) - for config_rule in device_data.device_config.config_rules - ] - LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format( - '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules]))) - final_config_rules = DEVICE_EMU_CONFIG_RULES[1:] + DEVICE_EMU_RECONFIG_RULES[1:] # remove '/dev/rsrc1/value' - for config_rule in final_config_rules: - config_rule = ( - ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value']) - assert config_rule in config_rules - - -def test_device_emulated_deconfigure( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now - assert driver is not None - - driver_config = driver.GetConfig() - LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - - DEVICE_EMU_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_EMU) - DEVICE_EMU_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_DECONFIG_RULES) - device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_DECONFIG_RULES)) - - driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - assert len(driver_config) == 0 - - device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID)) - assert len(device_data.device_config.config_rules) == 0 - - -def test_device_emulated_delete( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - device_client.DeleteDevice(DeviceId(**DEVICE_EMU_ID)) - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID, {}) - assert driver is None - - -# ----- Test Device Driver OpenConfig ---------------------------------------------------------------------------------- - -def test_device_openconfig_add_error_cases( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - if not ENABLE_OPENCONFIG: return # if there is no device to test against, asusme test is silently passed. - - with pytest.raises(grpc.RpcError) as e: - DEVICE_OC_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_OC) - DEVICE_OC_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONNECT_RULES) - DEVICE_OC_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONFIG_RULES) - device_client.AddDevice(Device(**DEVICE_OC_WITH_EXTRA_RULES)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg_head = 'device.device_config.config_rules([' - msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\ - 'with "_connect/" tag. Others should be configured after adding the device.' - except_msg = str(e.value.details()) - assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail) - - -def test_device_openconfig_add_correct( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - if not ENABLE_OPENCONFIG: return # if there is no device to test against, asusme test is silently passed. - - DEVICE_OC_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_OC) - DEVICE_OC_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONNECT_RULES) - device_client.AddDevice(Device(**DEVICE_OC_WITH_CONNECT_RULES)) - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now - assert driver is not None - - -def test_device_openconfig_get( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - if not ENABLE_OPENCONFIG: return # if there is no device to test against, asusme test is silently passed. - - initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_OC_ID)) - LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config))) - - device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID)) - LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data))) - - -def test_device_openconfig_configure( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - if not ENABLE_OPENCONFIG: return # if there is no device to test against, asusme test is silently passed. - - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now - assert driver is not None - - # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly. - #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - #LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - - DEVICE_OC_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_OC) - DEVICE_OC_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONFIG_RULES) - device_client.ConfigureDevice(Device(**DEVICE_OC_WITH_CONFIG_RULES)) - - # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly. - #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - #LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - - device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID)) - config_rules = [ - (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value) - for config_rule in device_data.device_config.config_rules - ] - LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format( - '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules]))) - for config_rule in DEVICE_OC_CONFIG_RULES: - config_rule = ( - ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value']) - assert config_rule in config_rules - - -def test_device_openconfig_deconfigure( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - if not ENABLE_OPENCONFIG: return # if there is no device to test against, asusme test is silently passed. - - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now - assert driver is not None - - # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly. - #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - #LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - - DEVICE_OC_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_OC) - DEVICE_OC_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_OC_DECONFIG_RULES) - device_client.ConfigureDevice(Device(**DEVICE_OC_WITH_DECONFIG_RULES)) - - # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly. - #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0)) - #LOGGER.info('driver_config = {:s}'.format(str(driver_config))) - - device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID)) - config_rules = [ - (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value) - for config_rule in device_data.device_config.config_rules - ] - LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format( - '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules]))) - for config_rule in DEVICE_OC_DECONFIG_RULES: - action_set = ConfigActionEnum.Name(ConfigActionEnum.CONFIGACTION_SET) - config_rule = (action_set, config_rule['resource_key'], config_rule['resource_value']) - assert config_rule not in config_rules - - -def test_device_openconfig_delete( - context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name - device_service : DeviceService): # pylint: disable=redefined-outer-name - - if not ENABLE_OPENCONFIG: return # if there is no device to test against, asusme test is silently passed. - - device_client.DeleteDevice(DeviceId(**DEVICE_OC_ID)) - driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID, {}) - assert driver is None diff --git a/src/device/tests/test_unitary_driverapi.py b/src/device/tests/test_unitary_driverapi.py index 027e7775eae4a3f7a19c056266e1fc807b09cf2d..ac7231cf76d4bcba0ea37da0cab781e21bc1c560 100644 --- a/src/device/tests/test_unitary_driverapi.py +++ b/src/device/tests/test_unitary_driverapi.py @@ -37,44 +37,44 @@ def device_driverapi_emulated(): yield _driver _driver.Disconnect() -def test_device_driverapi_emulated_setconfig( - device_driverapi_emulated : EmulatedDriver): # pylint: disable=redefined-outer-name - +def test_device_driverapi_emulated_setconfig(device_driverapi_emulated : EmulatedDriver): + # should work results = device_driverapi_emulated.SetConfig(DEVICE_CONFIG_IF1) - LOGGER.info('results:\n{:s}'.format('\n'.join(map(str, results)))) + LOGGER.info('results:\n{}'.format('\n'.join(map(str, results)))) assert len(results) == len(DEVICE_CONFIG_IF1) for result in results: assert isinstance(result, bool) and result results = device_driverapi_emulated.SetConfig(DEVICE_CONFIG_IF2) - LOGGER.info('results:\n{:s}'.format('\n'.join(map(str, results)))) + LOGGER.info('results:\n{}'.format('\n'.join(map(str, results)))) assert len(results) == len(DEVICE_CONFIG_IF2) for result in results: assert isinstance(result, bool) and result -def test_device_driverapi_emulated_getconfig( - device_driverapi_emulated : EmulatedDriver): # pylint: disable=redefined-outer-name - +def test_device_driverapi_emulated_getconfig(device_driverapi_emulated : EmulatedDriver): stored_config = device_driverapi_emulated.GetConfig() - LOGGER.info('stored_config:\n{:s}'.format('\n'.join(map(str, stored_config)))) + LOGGER.info('stored_config:\n{}'.format('\n'.join(map(str, stored_config)))) assert len(stored_config) == len(DEVICE_CONFIG_IF1) + len(DEVICE_CONFIG_IF2) for config_row in stored_config: assert (config_row in DEVICE_CONFIG_IF1) or (config_row in DEVICE_CONFIG_IF2) for config_row in DEVICE_CONFIG_IF1: assert config_row in stored_config for config_row in DEVICE_CONFIG_IF2: assert config_row in stored_config + # should work stored_config = device_driverapi_emulated.GetConfig([PATH_IF.format('IF2')]) - LOGGER.info('stored_config:\n{:s}'.format('\n'.join(map(str, stored_config)))) + LOGGER.info('stored_config:\n{}'.format('\n'.join(map(str, stored_config)))) + assert len(stored_config) == 1 + stored_config = stored_config[0] + LOGGER.info('stored_config[0]:\n{}'.format('\n'.join(map(str, stored_config)))) assert len(stored_config) == len(DEVICE_CONFIG_IF2) for config_row in stored_config: assert config_row in DEVICE_CONFIG_IF2 for config_row in DEVICE_CONFIG_IF2: assert config_row in stored_config -def test_device_driverapi_emulated_deleteconfig( - device_driverapi_emulated : EmulatedDriver): # pylint: disable=redefined-outer-name - - results = device_driverapi_emulated.DeleteConfig([(PATH_ADDRIPV4.format('IF2', 0, '10.2.0.1'), '')]) - LOGGER.info('results:\n{:s}'.format('\n'.join(map(str, results)))) +def test_device_driverapi_emulated_deleteconfig(device_driverapi_emulated : EmulatedDriver): + # should work + results = device_driverapi_emulated.DeleteConfig([PATH_ADDRIPV4.format('IF2', 0, '10.2.0.1')]) + LOGGER.info('results:\n{}'.format('\n'.join(map(str, results)))) assert (len(results) == 1) and isinstance(results[0], bool) and results[0] stored_config = device_driverapi_emulated.GetConfig() - LOGGER.info('stored_config:\n{:s}'.format('\n'.join(map(str, stored_config)))) + LOGGER.info('stored_config:\n{}'.format('\n'.join(map(str, stored_config)))) device_config_if2 = list(filter(lambda row: '10.2.0.1' not in row[0], copy.deepcopy(DEVICE_CONFIG_IF2))) assert len(stored_config) == len(DEVICE_CONFIG_IF1) + len(device_config_if2) @@ -82,9 +82,8 @@ def test_device_driverapi_emulated_deleteconfig( for config_row in DEVICE_CONFIG_IF1: assert config_row in stored_config for config_row in device_config_if2: assert config_row in stored_config -def test_device_driverapi_emulated_subscriptions( - device_driverapi_emulated : EmulatedDriver): # pylint: disable=redefined-outer-name - +def test_device_driverapi_emulated_subscriptions(device_driverapi_emulated : EmulatedDriver): + # should work duration = 10.0 interval = 1.5 results = device_driverapi_emulated.SubscribeState([ @@ -93,21 +92,21 @@ def test_device_driverapi_emulated_subscriptions( (DEVICE_STATE_IF2_TX_PKTS, duration, interval), (DEVICE_STATE_IF2_RX_PKTS, duration, interval), ]) - LOGGER.info('results:\n{:s}'.format('\n'.join(map(str, results)))) + LOGGER.info('results:\n{}'.format('\n'.join(map(str, results)))) assert len(results) == 4 for result in results: assert isinstance(result, bool) and result stored_config = device_driverapi_emulated.GetConfig() - LOGGER.info('stored_config:\n{:s}'.format('\n'.join(map(str, stored_config)))) + LOGGER.info('stored_config:\n{}'.format('\n'.join(map(str, stored_config)))) time.sleep(duration + 1.0) # let time to generate samples, plus 1 second extra time samples = [] for sample in device_driverapi_emulated.GetState(blocking=False): - LOGGER.info('sample: {:s}'.format(str(sample))) + LOGGER.info('sample: {}'.format(str(sample))) timestamp,resource_key,resource_value = sample samples.append((timestamp, resource_key, resource_value)) - LOGGER.info('samples:\n{:s}'.format('\n'.join(map(str, samples)))) + LOGGER.info('samples:\n{}'.format('\n'.join(map(str, samples)))) assert len(samples) == 4 * (math.floor(duration/interval) + 1) results = device_driverapi_emulated.UnsubscribeState([ @@ -116,12 +115,12 @@ def test_device_driverapi_emulated_subscriptions( (DEVICE_STATE_IF2_TX_PKTS, 10.0, 1.5), (DEVICE_STATE_IF2_RX_PKTS, 10.0, 1.5), ]) - LOGGER.info('results:\n{:s}'.format('\n'.join(map(str, results)))) + LOGGER.info('results:\n{}'.format('\n'.join(map(str, results)))) assert len(results) == 4 for result in results: assert isinstance(result, bool) and result stored_config = device_driverapi_emulated.GetConfig() - LOGGER.info('stored_config:\n{:s}'.format('\n'.join(map(str, stored_config)))) + LOGGER.info('stored_config:\n{}'.format('\n'.join(map(str, stored_config)))) device_config_if2 = list(filter(lambda row: '10.2.0.1' not in row[0], copy.deepcopy(DEVICE_CONFIG_IF2))) assert len(stored_config) == len(DEVICE_CONFIG_IF1) + len(device_config_if2) for config_row in stored_config: assert (config_row in DEVICE_CONFIG_IF1) or (config_row in device_config_if2) diff --git a/src/device/tests/test_unitary_service.py b/src/device/tests/test_unitary_service.py new file mode 100644 index 0000000000000000000000000000000000000000..8d9591dd6492395a44adc25e4a54eaebc8ff9121 --- /dev/null +++ b/src/device/tests/test_unitary_service.py @@ -0,0 +1,270 @@ +import copy, grpc, logging, pytest +from google.protobuf.json_format import MessageToDict +from common.database.Factory import get_database, DatabaseEngineEnum +from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID +from common.database.api.context.topology.device.OperationalStatus import OperationalStatus +from common.tests.Assertions import validate_device_id, validate_empty +from device.client.DeviceClient import DeviceClient +from device.proto.context_pb2 import Device, DeviceId +from device.service.DeviceService import DeviceService +from device.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD + +port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +# use "copy.deepcopy" to prevent propagating forced changes during tests +CONTEXT_ID = {'contextUuid': {'uuid': DEFAULT_CONTEXT_ID}} +TOPOLOGY_ID = {'contextId': copy.deepcopy(CONTEXT_ID), 'topoId': {'uuid': DEFAULT_TOPOLOGY_ID}} +DEVICE_ID = {'device_id': {'uuid': 'DEV1'}} +DEVICE = { + 'device_id': copy.deepcopy(DEVICE_ID), + 'device_type': 'ROADM', + 'device_config': {'device_config': ''}, + 'devOperationalStatus': OperationalStatus.ENABLED.value, + 'endpointList' : [ + { + 'port_id': {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': copy.deepcopy(DEVICE_ID), 'port_id': {'uuid' : 'EP2'}}, + 'port_type': 'WDM' + }, + { + 'port_id': {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': copy.deepcopy(DEVICE_ID), 'port_id': {'uuid' : 'EP3'}}, + 'port_type': 'WDM' + }, + { + 'port_id': {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': copy.deepcopy(DEVICE_ID), 'port_id': {'uuid' : 'EP4'}}, + 'port_type': 'WDM' + }, + ] +} + +@pytest.fixture(scope='session') +def device_database(): + _database = get_database(engine=DatabaseEngineEnum.INMEMORY) + return _database + +@pytest.fixture(scope='session') +def device_service(device_database): + _service = DeviceService( + device_database, port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD) + _service.start() + yield _service + _service.stop() + +@pytest.fixture(scope='session') +def device_client(device_service): + _client = DeviceClient(address='127.0.0.1', port=port) + yield _client + _client.close() + +def test_add_device_wrong_attributes(device_client : DeviceClient): + # should fail with device uuid is empty + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['device_id']['device_id']['uuid'] = '' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'device.device_id.device_id.uuid() is out of range: '\ + 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' + assert e.value.details() == msg + + # should fail with device type is empty + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['device_type'] = '' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'device.device_type() is out of range: '\ + 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' + assert e.value.details() == msg + + # should fail with wrong device operational status + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['devOperationalStatus'] = OperationalStatus.KEEP_STATE.value + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'Method(AddDevice) does not accept OperationalStatus(KEEP_STATE). '\ + 'Permitted values for Method(AddDevice) are OperationalStatus([\'DISABLED\', \'ENABLED\']).' + assert e.value.details() == msg + +def test_add_device_wrong_endpoint(device_client : DeviceClient): + # should fail with unsupported endpoint context + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][0]['port_id']['topoId']['contextId']['contextUuid']['uuid'] = 'wrong-context' + request = Device(**copy_device) + device_client.AddDevice(request) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'Context(wrong-context) in Endpoint(#0) of '\ + 'Context(admin)/Topology(admin)/Device(DEV1) mismatches acceptable Contexts({\'admin\'}). '\ + 'Optionally, leave field empty to use predefined Context(admin).' + assert e.value.details() == msg + + # should fail with unsupported endpoint topology + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][0]['port_id']['topoId']['topoId']['uuid'] = 'wrong-topo' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'Context(admin)/Topology(wrong-topo) in Endpoint(#0) of '\ + 'Context(admin)/Topology(admin)/Device(DEV1) mismatches acceptable Topologies({\'admin\'}). '\ + 'Optionally, leave field empty to use predefined Topology(admin).' + assert e.value.details() == msg + + # should fail with wrong endpoint device + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][0]['port_id']['dev_id']['device_id']['uuid'] = 'wrong-device' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'Context(admin)/Topology(admin)/Device(wrong-device) in Endpoint(#0) of '\ + 'Context(admin)/Topology(admin)/Device(DEV1) mismatches acceptable Devices({\'DEV1\'}). '\ + 'Optionally, leave field empty to use predefined Device(DEV1).' + assert e.value.details() == msg + + # should fail with endpoint port uuid is empty + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][0]['port_id']['port_id']['uuid'] = '' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'endpoint_id[#0].port_id.uuid() is out of range: '\ + 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' + assert e.value.details() == msg + + # should fail with endpoint port type is empty + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][0]['port_type'] = '' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'endpoint[#0].port_type() is out of range: '\ + 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' + assert e.value.details() == msg + + # should fail with duplicate port in device + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][1]['port_id']['port_id']['uuid'] = 'EP2' + device_client.AddDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'Duplicated Context(admin)/Topology(admin)/Device(DEV1)/Port(EP2) in Endpoint(#1) of '\ + 'Context(admin)/Topology(admin)/Device(DEV1).' + assert e.value.details() == msg + +def test_add_device(device_client : DeviceClient): + # should work + validate_device_id(MessageToDict( + device_client.AddDevice(Device(**DEVICE)), + including_default_value_fields=True, preserving_proto_field_name=True, + use_integers_for_enums=False)) + +def test_add_device_duplicate(device_client : DeviceClient): + # should fail with device already exists + with pytest.raises(grpc._channel._InactiveRpcError) as e: + device_client.AddDevice(Device(**DEVICE)) + assert e.value.code() == grpc.StatusCode.ALREADY_EXISTS + msg = 'Context(admin)/Topology(admin)/Device(DEV1) already exists in the database.' + assert e.value.details() == msg + +def test_delete_device_empty_uuid(device_client : DeviceClient): + # should fail with device uuid is empty + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device_id = copy.deepcopy(DEVICE_ID) + copy_device_id['device_id']['uuid'] = '' + device_client.DeleteDevice(DeviceId(**copy_device_id)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'device_id.device_id.uuid() is out of range: '\ + 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' + assert e.value.details() == msg + +def test_delete_device_not_found(device_client : DeviceClient): + # should fail with device not found + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device_id = copy.deepcopy(DEVICE_ID) + copy_device_id['device_id']['uuid'] = 'wrong-device-id' + device_client.DeleteDevice(DeviceId(**copy_device_id)) + assert e.value.code() == grpc.StatusCode.NOT_FOUND + msg = 'Context(admin)/Topology(admin)/Device(wrong-device-id) does not exist in the database.' + assert e.value.details() == msg + +def test_delete_device(device_client : DeviceClient): + # should work + validate_empty(MessageToDict( + device_client.DeleteDevice(DeviceId(**DEVICE_ID)), + including_default_value_fields=True, preserving_proto_field_name=True, + use_integers_for_enums=False)) + +def test_configure_device_empty_device_uuid(device_client : DeviceClient): + # should fail with device uuid is empty + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['device_id']['device_id']['uuid'] = '' + device_client.ConfigureDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'device.device_id.device_id.uuid() is out of range: '\ + 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' + assert e.value.details() == msg + +def test_configure_device_not_found(device_client : DeviceClient): + # should fail with device not found + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['device_id']['device_id']['uuid'] = 'wrong-device-id' + device_client.ConfigureDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.NOT_FOUND + msg = 'Context(admin)/Topology(admin)/Device(wrong-device-id) does not exist in the database.' + assert e.value.details() == msg + +def test_add_device_default_endpoint_context_topology_device(device_client : DeviceClient): + # should work + copy_device = copy.deepcopy(DEVICE) + copy_device['endpointList'][0]['port_id']['topoId']['contextId']['contextUuid']['uuid'] = '' + copy_device['endpointList'][0]['port_id']['topoId']['topoId']['uuid'] = '' + copy_device['endpointList'][0]['port_id']['dev_id']['device_id']['uuid'] = '' + validate_device_id(MessageToDict( + device_client.AddDevice(Device(**copy_device)), + including_default_value_fields=True, preserving_proto_field_name=True, + use_integers_for_enums=False)) + +def test_configure_device_wrong_attributes(device_client : DeviceClient): + # should fail with device type is wrong + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['device_type'] = 'wrong-type' + device_client.ConfigureDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + msg = 'Device(DEV1) has Type(ROADM) in the database. Cannot be changed to Type(wrong-type).' + assert e.value.details() == msg + + # should fail with endpoints cannot be modified + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + device_client.ConfigureDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT + assert e.value.details() == 'Endpoints belonging to Device(DEV1) cannot be modified.' + + # should fail with any change detected + with pytest.raises(grpc._channel._InactiveRpcError) as e: + copy_device = copy.deepcopy(DEVICE) + copy_device['device_config']['device_config'] = '' + copy_device['devOperationalStatus'] = OperationalStatus.KEEP_STATE.value + copy_device['endpointList'].clear() + device_client.ConfigureDevice(Device(**copy_device)) + assert e.value.code() == grpc.StatusCode.ABORTED + msg = 'Any change has been requested for Device(DEV1). '\ + 'Either specify a new configuration or a new device operational status.' + assert e.value.details() == msg + +def test_configure_device(device_client : DeviceClient): + # should work + copy_device = copy.deepcopy(DEVICE) + copy_device['device_config']['device_config'] = '' + copy_device['devOperationalStatus'] = OperationalStatus.DISABLED.value + copy_device['endpointList'].clear() + validate_device_id(MessageToDict( + device_client.ConfigureDevice(Device(**copy_device)), + including_default_value_fields=True, preserving_proto_field_name=True, + use_integers_for_enums=False)) diff --git a/src/monitoring/.gitlab-ci.yml b/src/monitoring/.gitlab-ci.yml index 85e0cdcb846710f776af09377db41d7acbde6863..5d0ade4ae598e7079dce4772afbaf9e3c368dd4f 100644 --- a/src/monitoring/.gitlab-ci.yml +++ b/src/monitoring/.gitlab-ci.yml @@ -11,7 +11,7 @@ build monitoring: - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" after_script: - - docker rmi $(docker images --quiet --filter=dangling=true) +# - docker rmi $(docker images --quiet --filter=dangling=true) rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' @@ -19,7 +19,6 @@ build monitoring: - src/$IMAGE_NAME/**/*.{py,in,yml} - src/$IMAGE_NAME/Dockerfile - src/$IMAGE_NAME/tests/*.py - - src/$IMAGE_NAME/tests/Dockerfile - manifests/$IMAGE_NAME.yaml - .gitlab-ci.yml @@ -38,8 +37,10 @@ unit test monitoring: - if docker container ls | grep $IMAGE_NAME; then docker rm -f $IMAGE_NAME; else echo "$IMAGE_NAME image is not in the system"; fi script: - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" - - docker run --name influxdb -d -p 8086:8086 -e INFLUXDB_DB=$INFLUXDB_DATABASE -e INFLUXDB_ADMIN_USER=$INFLUXDB_USER -e INFLUXDB_ADMIN_PASSWORD=$INFLUXDB_PASSWORD -e INXLUXDB_HTTP_AUTH_ENABLED=True --network=teraflowbridge --rm influxdb:1.8 + - docker run --name influxdb -d -p 8086:8086 -e INFLUXDB_DB=$INFLUXDB_DATABASE -e INFLUXDB_ADMIN_USER=$INFLUXDB_USER -e INFLUXDB_ADMIN_PASSWORD=$INFLUXDB_PASSWORD -e INFLUXDB_HTTP_AUTH_ENABLED=True --network=teraflowbridge --rm influxdb:1.8 + - sleep 10 - docker run --name $IMAGE_NAME -d -p 7070:7070 --env INFLUXDB_USER=$INFLUXDB_USER --env INFLUXDB_PASSWORD=$INFLUXDB_PASSWORD --env INFLUXDB_DATABASE=$INFLUXDB_DATABASE --env INFLUXDB_HOSTNAME=influxdb -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge --rm $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG + - sleep 30 - docker ps -a - docker exec -i $IMAGE_NAME bash -c "pytest --junitxml=/opt/results/report.xml" after_script: @@ -71,10 +72,10 @@ deploy monitoring: - unit test monitoring # - integ_test execute script: - - 'sed -i "s/$IMAGE_NAME:.*/$IMAGE_NAME:$IMAGE_TAG/" manifests/$IMAGE_NAME.yaml' + - 'sed -i "s/$IMAGE_NAME:.*/$IMAGE_NAME:$IMAGE_TAG/" manifests/$IMAGE_NAMEservice.yaml' - kubectl version - kubectl get all - - kubectl apply -f "manifests/$IMAGE_NAME.yaml" + - kubectl apply -f "manifests/$IMAGE_NAMEservice.yaml" - kubectl get all # environment: # name: test @@ -85,4 +86,4 @@ deploy monitoring: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' when: manual - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' - when: manual \ No newline at end of file + when: manual diff --git a/src/monitoring/Dockerfile b/src/monitoring/Dockerfile index e274b0a518bad5e3947c22b3fd925ef052d9918a..af2fd608521c297f7aa97b45f0e3fc5d88e5615c 100644 --- a/src/monitoring/Dockerfile +++ b/src/monitoring/Dockerfile @@ -22,6 +22,13 @@ WORKDIR /var/teraflow # Create module sub-folders RUN mkdir -p /var/teraflow/monitoring RUN mkdir -p /var/teraflow/common +RUN mkdir -p /var/teraflow/common/tools +RUN mkdir -p /var/teraflow/common/rpc_method_wrapper +RUN mkdir -p /var/teraflow/device +RUN mkdir -p /var/teraflow/device/proto +RUN mkdir -p /var/teraflow/device/client +RUN mkdir -p /var/teraflow/context + # Get Python packages per module COPY monitoring/requirements.in requirements.in @@ -30,6 +37,15 @@ RUN python3 -m pip install -r requirements.txt # add files into working directory COPY monitoring/. monitoring -COPY common/logger.py common +COPY device/proto/. device/proto +COPY device/client/. device/client +COPY device/Config.py device +COPY common/. common +COPY context/. context + +RUN rm -r common/message_broker/tests +RUN rm -r common/orm/tests +RUN rm -r common/rpc_method_wrapper/tests +RUN rm -r context/tests/test_unitary.py ENTRYPOINT ["python", "-m", "monitoring.service"] diff --git a/src/monitoring/client/monitoring_client.py b/src/monitoring/client/monitoring_client.py index ff16c0c37b2af1ec5bcdd84ad22ead8b1d020d67..c3ab508c947ae07835801ad724f4589af92379c8 100644 --- a/src/monitoring/client/monitoring_client.py +++ b/src/monitoring/client/monitoring_client.py @@ -21,25 +21,19 @@ class MonitoringClient: LOGGER.info('CreateKpi: {}'.format(request)) response = self.server.CreateKpi(request) LOGGER.info('CreateKpi result: {}'.format(response)) - return monitoring_pb2.KpiId() + return response def MonitorKpi(self, request): LOGGER.info('MonitorKpi: {}'.format(request)) response = self.server.MonitorKpi(request) LOGGER.info('MonitorKpi result: {}'.format(response)) - return context_pb2.Empty() - - def MonitorDeviceKpi(self, request): - LOGGER.info('MonitorDeviceKpi: {}'.format(request)) - response = self.server.MonitorDeviceKpi(request) - LOGGER.info('MonitorDeviceKpi result: {}'.format(response)) - return context_pb2.Empty() + return response def IncludeKpi(self, request): LOGGER.info('IncludeKpi: {}'.format(request)) response = self.server.IncludeKpi(request) LOGGER.info('IncludeKpi result: {}'.format(response)) - return context_pb2.Empty() + return response def GetStreamKpi(self, request): LOGGER.info('GetStreamKpi: {}'.format(request)) @@ -53,17 +47,15 @@ class MonitoringClient: LOGGER.info('GetInstantKpi result: {}'.format(response)) return monitoring_pb2.Kpi() + def GetKpiDescriptor(self, request): + LOGGER.info('GetKpiDescriptor: {}'.format(request)) + response = self.server.GetKpiDescriptor(request) + LOGGER.info('GetKpiDescriptor result: {}'.format(response)) + return response if __name__ == '__main__': # get port port = sys.argv[1] if len(sys.argv) > 1 else '7070' - # form request - kpi_request = monitoring_pb2.KpiRequest() - kpi_request.device_id.device_id = 'KPIID0000' # pylint: disable=maybe-no-member - kpi_request.kpiDescription = 'KPI Description' - kpi_request.kpi_sample_type = monitoring_pb2.KpiSampleType.PACKETS_TRANSMITTED - # make call to server client = MonitoringClient(port=port) - response=client.IncludeKpi(kpi_request) diff --git a/src/monitoring/proto/context_pb2.py b/src/monitoring/proto/context_pb2.py index 8b4848bc33bfb0eba76590c8a3a627b2db84ca9f..658c58897615b33a435c7004d05b0a291abf95b7 100644 --- a/src/monitoring/proto/context_pb2.py +++ b/src/monitoring/proto/context_pb2.py @@ -12,6 +12,7 @@ from google.protobuf import symbol_database as _symbol_database _sym_db = _symbol_database.Default() +from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -20,8 +21,9 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"K\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' -) + serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"K\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\"\x9f\x01\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\x12\x38\n\x0fkpi_sample_type\x18\x04 \x01(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' + , + dependencies=[kpi__sample__types__pb2.DESCRIPTOR,]) _EVENTTYPEENUM = _descriptor.EnumDescriptor( name='EventTypeEnum', @@ -53,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3468, - serialized_end=3574, + serialized_start=3551, + serialized_end=3657, ) _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM) @@ -99,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3577, - serialized_end=3774, + serialized_start=3660, + serialized_end=3857, ) _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM) @@ -130,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3777, - serialized_end=3920, + serialized_start=3860, + serialized_end=4003, ) _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM) @@ -166,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3923, - serialized_end=4052, + serialized_start=4006, + serialized_end=4135, ) _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM) @@ -202,8 +204,8 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4055, - serialized_end=4191, + serialized_start=4138, + serialized_end=4274, ) _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM) @@ -233,8 +235,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4193, - serialized_end=4286, + serialized_start=4276, + serialized_end=4369, ) _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM) @@ -286,8 +288,8 @@ _EMPTY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=26, - serialized_end=33, + serialized_start=50, + serialized_end=57, ) @@ -318,8 +320,8 @@ _UUID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=35, - serialized_end=55, + serialized_start=59, + serialized_end=79, ) @@ -357,8 +359,8 @@ _EVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=57, - serialized_end=127, + serialized_start=81, + serialized_end=151, ) @@ -389,8 +391,8 @@ _CONTEXTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=129, - serialized_end=177, + serialized_start=153, + serialized_end=201, ) @@ -442,8 +444,8 @@ _CONTEXT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=180, - serialized_end=362, + serialized_start=204, + serialized_end=386, ) @@ -474,8 +476,8 @@ _CONTEXTIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=364, - serialized_end=420, + serialized_start=388, + serialized_end=444, ) @@ -506,8 +508,8 @@ _CONTEXTLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=422, - serialized_end=471, + serialized_start=446, + serialized_end=495, ) @@ -545,8 +547,8 @@ _CONTEXTEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=473, - serialized_end=558, + serialized_start=497, + serialized_end=582, ) @@ -584,8 +586,8 @@ _TOPOLOGYID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=560, - serialized_end=650, + serialized_start=584, + serialized_end=674, ) @@ -630,8 +632,8 @@ _TOPOLOGY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=652, - serialized_end=778, + serialized_start=676, + serialized_end=802, ) @@ -662,8 +664,8 @@ _TOPOLOGYIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=780, - serialized_end=839, + serialized_start=804, + serialized_end=863, ) @@ -694,8 +696,8 @@ _TOPOLOGYLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=841, - serialized_end=894, + serialized_start=865, + serialized_end=918, ) @@ -733,8 +735,8 @@ _TOPOLOGYEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=896, - serialized_end=984, + serialized_start=920, + serialized_end=1008, ) @@ -765,8 +767,8 @@ _DEVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=986, - serialized_end=1032, + serialized_start=1010, + serialized_end=1056, ) @@ -832,8 +834,8 @@ _DEVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1035, - serialized_end=1317, + serialized_start=1059, + serialized_end=1341, ) @@ -864,8 +866,8 @@ _DEVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1319, - serialized_end=1376, + serialized_start=1343, + serialized_end=1400, ) @@ -896,8 +898,8 @@ _DEVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1378, - serialized_end=1431, + serialized_start=1402, + serialized_end=1455, ) @@ -928,8 +930,8 @@ _DEVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1433, - serialized_end=1479, + serialized_start=1457, + serialized_end=1503, ) @@ -967,8 +969,8 @@ _DEVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1481, - serialized_end=1563, + serialized_start=1505, + serialized_end=1587, ) @@ -999,8 +1001,8 @@ _LINKID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1565, - serialized_end=1607, + serialized_start=1589, + serialized_end=1631, ) @@ -1038,8 +1040,8 @@ _LINK = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1609, - serialized_end=1697, + serialized_start=1633, + serialized_end=1721, ) @@ -1070,8 +1072,8 @@ _LINKIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1699, - serialized_end=1746, + serialized_start=1723, + serialized_end=1770, ) @@ -1102,8 +1104,8 @@ _LINKLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1748, - serialized_end=1788, + serialized_start=1772, + serialized_end=1812, ) @@ -1141,8 +1143,8 @@ _LINKEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1790, - serialized_end=1866, + serialized_start=1814, + serialized_end=1890, ) @@ -1180,8 +1182,8 @@ _SERVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1868, - serialized_end=1956, + serialized_start=1892, + serialized_end=1980, ) @@ -1247,8 +1249,8 @@ _SERVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1959, - serialized_end=2253, + serialized_start=1983, + serialized_end=2277, ) @@ -1279,8 +1281,8 @@ _SERVICESTATUS = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2255, - serialized_end=2322, + serialized_start=2279, + serialized_end=2346, ) @@ -1311,8 +1313,8 @@ _SERVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2324, - serialized_end=2382, + serialized_start=2348, + serialized_end=2406, ) @@ -1343,8 +1345,8 @@ _SERVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2384, - serialized_end=2440, + serialized_start=2408, + serialized_end=2464, ) @@ -1375,8 +1377,8 @@ _SERVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2442, - serialized_end=2491, + serialized_start=2466, + serialized_end=2515, ) @@ -1414,8 +1416,8 @@ _SERVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2493, - serialized_end=2578, + serialized_start=2517, + serialized_end=2602, ) @@ -1460,8 +1462,8 @@ _ENDPOINTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2581, - serialized_end=2711, + serialized_start=2605, + serialized_end=2735, ) @@ -1499,8 +1501,8 @@ _ENDPOINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2713, - serialized_end=2788, + serialized_start=2737, + serialized_end=2812, ) @@ -1533,6 +1535,13 @@ _CONFIGRULE = _descriptor.Descriptor( 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='kpi_sample_type', full_name='context.ConfigRule.kpi_sample_type', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=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), ], extensions=[ ], @@ -1545,8 +1554,8 @@ _CONFIGRULE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2790, - serialized_end=2891, + serialized_start=2815, + serialized_end=2974, ) @@ -1584,8 +1593,8 @@ _CONSTRAINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2893, - serialized_end=2956, + serialized_start=2976, + serialized_end=3039, ) @@ -1616,8 +1625,8 @@ _CONNECTIONID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2958, - serialized_end=3012, + serialized_start=3041, + serialized_end=3095, ) @@ -1662,8 +1671,8 @@ _CONNECTION = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3015, - serialized_end=3156, + serialized_start=3098, + serialized_end=3239, ) @@ -1694,8 +1703,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3158, - serialized_end=3223, + serialized_start=3241, + serialized_end=3306, ) @@ -1726,8 +1735,8 @@ _CONNECTIONLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3225, - serialized_end=3283, + serialized_start=3308, + serialized_end=3366, ) @@ -1772,8 +1781,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3285, - serialized_end=3379, + serialized_start=3368, + serialized_end=3462, ) @@ -1811,8 +1820,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3381, - serialized_end=3466, + serialized_start=3464, + serialized_end=3549, ) _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM @@ -1871,6 +1880,7 @@ _ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID _ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID _ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID _CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM +_CONFIGRULE.fields_by_name['kpi_sample_type'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID _CONNECTION.fields_by_name['related_service_id'].message_type = _SERVICEID @@ -2224,8 +2234,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=4289, - serialized_end=5990, + serialized_start=4372, + serialized_end=6073, methods=[ _descriptor.MethodDescriptor( name='ListContextIds', diff --git a/src/monitoring/proto/kpi_sample_types_pb2.py b/src/monitoring/proto/kpi_sample_types_pb2.py index ad22554ec352d0aeae644fdce00c0f28996ed73b..31fbaa216bca629a4de4272091c490982c1aa166 100644 --- a/src/monitoring/proto/kpi_sample_types_pb2.py +++ b/src/monitoring/proto/kpi_sample_types_pb2.py @@ -2,6 +2,7 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: kpi_sample_types.proto """Generated protocol buffer code.""" +from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -15,15 +16,62 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='kpi_sample_types.proto', - package='', + package='kpi_sample_types', syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x16kpi_sample_types.protob\x06proto3' + serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*x\n\rKpiSampleType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x17\n\x13PACKETS_TRANSMITTED\x10\x65\x12\x14\n\x10PACKETS_RECEIVED\x10\x66\x12\x16\n\x11\x42YTES_TRANSMITTED\x10\xc9\x01\x12\x13\n\x0e\x42YTES_RECEIVED\x10\xca\x01\x62\x06proto3' ) +_KPISAMPLETYPE = _descriptor.EnumDescriptor( + name='KpiSampleType', + full_name='kpi_sample_types.KpiSampleType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKETS_TRANSMITTED', index=1, number=101, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKETS_RECEIVED', index=2, number=102, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BYTES_TRANSMITTED', index=3, number=201, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='BYTES_RECEIVED', index=4, number=202, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=44, + serialized_end=164, +) +_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) + +KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) +UNKNOWN = 0 +PACKETS_TRANSMITTED = 101 +PACKETS_RECEIVED = 102 +BYTES_TRANSMITTED = 201 +BYTES_RECEIVED = 202 +DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) diff --git a/src/monitoring/proto/monitoring_pb2.py b/src/monitoring/proto/monitoring_pb2.py index 7368609d2145f94cc3b746836a5297333151c738..b313ebb68f0da37a540898e8c362fd204a799076 100644 --- a/src/monitoring/proto/monitoring_pb2.py +++ b/src/monitoring/proto/monitoring_pb2.py @@ -2,7 +2,6 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: monitoring.proto """Generated protocol buffer code.""" -from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -13,6 +12,7 @@ _sym_db = _symbol_database.Default() from . import context_pb2 as context__pb2 +from . import kpi_sample_types_pb2 as kpi__sample__types__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -21,177 +21,53 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x10monitoring.proto\x12\nmonitoring\x1a\rcontext.proto\"\x84\x01\n\x10\x43reateKpiRequest\x12\x16\n\x0ekpiDescription\x18\x01 \x01(\t\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12\x32\n\x0fkpi_sample_type\x18\x03 \x01(\x0e\x32\x19.monitoring.KpiSampleType\"h\n\x11MonitorKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x18\n\x10\x63onnexion_time_s\x18\x02 \x01(\r\x12\x16\n\x0esample_rate_ms\x18\x03 \x01(\r\"i\n\x17MonitorDeviceKpiRequest\x12\x1c\n\x03kpi\x18\x01 \x01(\x0b\x32\x0f.monitoring.Kpi\x12\x18\n\x10\x63onnexion_time_s\x18\x02 \x01(\r\x12\x16\n\x0esample_rate_ms\x18\x03 \x01(\r\"s\n\x11IncludeKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x12\n\ntime_stamp\x18\x02 \x01(\t\x12\'\n\tkpi_value\x18\x03 \x01(\x0b\x32\x14.monitoring.KpiValue\"&\n\x05KpiId\x12\x1d\n\x06kpi_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xd6\x01\n\x03Kpi\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x16\n\x0ekpiDescription\x18\x03 \x01(\t\x12\'\n\tkpi_value\x18\x04 \x01(\x0b\x32\x14.monitoring.KpiValue\x12\x32\n\x0fkpi_sample_type\x18\x05 \x01(\x0e\x32\x19.monitoring.KpiSampleType\x12$\n\tdevice_id\x18\x06 \x01(\x0b\x32\x11.context.DeviceId\"a\n\x08KpiValue\x12\x10\n\x06intVal\x18\x01 \x01(\rH\x00\x12\x12\n\x08\x66loatVal\x18\x02 \x01(\x02H\x00\x12\x13\n\tstringVal\x18\x03 \x01(\tH\x00\x12\x11\n\x07\x62oolVal\x18\x04 \x01(\x08H\x00\x42\x07\n\x05value\"+\n\x07KpiList\x12 \n\x07kpiList\x18\x01 \x03(\x0b\x32\x0f.monitoring.Kpi*x\n\rKpiSampleType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x17\n\x13PACKETS_TRANSMITTED\x10\x65\x12\x14\n\x10PACKETS_RECEIVED\x10\x66\x12\x16\n\x11\x42YTES_TRANSMITTED\x10\xc9\x01\x12\x13\n\x0e\x42YTES_RECEIVED\x10\xca\x01\x32\x8b\x03\n\x11MonitoringService\x12>\n\tCreateKpi\x12\x1c.monitoring.CreateKpiRequest\x1a\x11.monitoring.KpiId\"\x00\x12=\n\nIncludeKpi\x12\x1d.monitoring.IncludeKpiRequest\x1a\x0e.context.Empty\"\x00\x12=\n\nMonitorKpi\x12\x1d.monitoring.MonitorKpiRequest\x1a\x0e.context.Empty\"\x00\x12I\n\x10MonitorDeviceKpi\x12#.monitoring.MonitorDeviceKpiRequest\x1a\x0e.context.Empty\"\x00\x12\x36\n\x0cGetStreamKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x30\x01\x12\x35\n\rGetInstantKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x62\x06proto3' + serialized_pb=b'\n\x10monitoring.proto\x12\nmonitoring\x1a\rcontext.proto\x1a\x16kpi_sample_types.proto\"\xda\x01\n\rKpiDescriptor\x12\x17\n\x0fkpi_description\x18\x01 \x01(\t\x12\x38\n\x0fkpi_sample_type\x18\x02 \x01(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\x12$\n\tdevice_id\x18\x03 \x01(\x0b\x32\x11.context.DeviceId\x12(\n\x0b\x65ndpoint_id\x18\x04 \x01(\x0b\x32\x13.context.EndPointId\x12&\n\nservice_id\x18\x05 \x01(\x0b\x32\x12.context.ServiceId\"p\n\x11MonitorKpiRequest\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x1b\n\x13sampling_duration_s\x18\x02 \x01(\x02\x12\x1b\n\x13sampling_interval_s\x18\x03 \x01(\x02\"&\n\x05KpiId\x12\x1d\n\x06kpi_id\x18\x01 \x01(\x0b\x32\r.context.Uuid\"d\n\x03Kpi\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\'\n\tkpi_value\x18\x04 \x01(\x0b\x32\x14.monitoring.KpiValue\"a\n\x08KpiValue\x12\x10\n\x06intVal\x18\x01 \x01(\rH\x00\x12\x12\n\x08\x66loatVal\x18\x02 \x01(\x02H\x00\x12\x13\n\tstringVal\x18\x03 \x01(\tH\x00\x12\x11\n\x07\x62oolVal\x18\x04 \x01(\x08H\x00\x42\x07\n\x05value\",\n\x07KpiList\x12!\n\x08kpi_list\x18\x01 \x03(\x0b\x32\x0f.monitoring.Kpi2\xf3\x02\n\x11MonitoringService\x12;\n\tCreateKpi\x12\x19.monitoring.KpiDescriptor\x1a\x11.monitoring.KpiId\"\x00\x12\x42\n\x10GetKpiDescriptor\x12\x11.monitoring.KpiId\x1a\x19.monitoring.KpiDescriptor\"\x00\x12/\n\nIncludeKpi\x12\x0f.monitoring.Kpi\x1a\x0e.context.Empty\"\x00\x12=\n\nMonitorKpi\x12\x1d.monitoring.MonitorKpiRequest\x1a\x0e.context.Empty\"\x00\x12\x36\n\x0cGetStreamKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x30\x01\x12\x35\n\rGetInstantKpi\x12\x11.monitoring.KpiId\x1a\x0f.monitoring.Kpi\"\x00\x62\x06proto3' , - dependencies=[context__pb2.DESCRIPTOR,]) + dependencies=[context__pb2.DESCRIPTOR,kpi__sample__types__pb2.DESCRIPTOR,]) -_KPISAMPLETYPE = _descriptor.EnumDescriptor( - name='KpiSampleType', - full_name='monitoring.KpiSampleType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='PACKETS_TRANSMITTED', index=1, number=101, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='PACKETS_RECEIVED', index=2, number=102, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='BYTES_TRANSMITTED', index=3, number=201, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='BYTES_RECEIVED', index=4, number=202, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - serialized_start=913, - serialized_end=1033, -) -_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE) - -KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE) -UNKNOWN = 0 -PACKETS_TRANSMITTED = 101 -PACKETS_RECEIVED = 102 -BYTES_TRANSMITTED = 201 -BYTES_RECEIVED = 202 -_CREATEKPIREQUEST = _descriptor.Descriptor( - name='CreateKpiRequest', - full_name='monitoring.CreateKpiRequest', +_KPIDESCRIPTOR = _descriptor.Descriptor( + name='KpiDescriptor', + full_name='monitoring.KpiDescriptor', filename=None, file=DESCRIPTOR, containing_type=None, create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='kpiDescription', full_name='monitoring.CreateKpiRequest.kpiDescription', index=0, + name='kpi_description', full_name='monitoring.KpiDescriptor.kpi_description', 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='device_id', full_name='monitoring.CreateKpiRequest.device_id', index=1, - number=2, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_type', full_name='monitoring.CreateKpiRequest.kpi_sample_type', index=2, - number=3, type=14, cpp_type=8, label=1, + name='kpi_sample_type', full_name='monitoring.KpiDescriptor.kpi_sample_type', index=1, + number=2, type=14, cpp_type=8, label=1, has_default_value=False, default_value=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), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=48, - serialized_end=180, -) - - -_MONITORKPIREQUEST = _descriptor.Descriptor( - name='MonitorKpiRequest', - full_name='monitoring.MonitorKpiRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.MonitorKpiRequest.kpi_id', index=0, - number=1, type=11, cpp_type=10, label=1, + name='device_id', full_name='monitoring.KpiDescriptor.device_id', index=2, + number=3, 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='connexion_time_s', full_name='monitoring.MonitorKpiRequest.connexion_time_s', index=1, - number=2, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sample_rate_ms', full_name='monitoring.MonitorKpiRequest.sample_rate_ms', index=2, - number=3, 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, - 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=182, - serialized_end=286, -) - - -_MONITORDEVICEKPIREQUEST = _descriptor.Descriptor( - name='MonitorDeviceKpiRequest', - full_name='monitoring.MonitorDeviceKpiRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='kpi', full_name='monitoring.MonitorDeviceKpiRequest.kpi', index=0, - number=1, type=11, cpp_type=10, label=1, + name='endpoint_id', full_name='monitoring.KpiDescriptor.endpoint_id', index=3, + number=4, 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='connexion_time_s', full_name='monitoring.MonitorDeviceKpiRequest.connexion_time_s', index=1, - number=2, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sample_rate_ms', full_name='monitoring.MonitorDeviceKpiRequest.sample_rate_ms', index=2, - number=3, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, + name='service_id', full_name='monitoring.KpiDescriptor.service_id', 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), @@ -207,37 +83,37 @@ _MONITORDEVICEKPIREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=288, - serialized_end=393, + serialized_start=72, + serialized_end=290, ) -_INCLUDEKPIREQUEST = _descriptor.Descriptor( - name='IncludeKpiRequest', - full_name='monitoring.IncludeKpiRequest', +_MONITORKPIREQUEST = _descriptor.Descriptor( + name='MonitorKpiRequest', + full_name='monitoring.MonitorKpiRequest', filename=None, file=DESCRIPTOR, containing_type=None, create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='kpi_id', full_name='monitoring.IncludeKpiRequest.kpi_id', index=0, + name='kpi_id', full_name='monitoring.MonitorKpiRequest.kpi_id', 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='time_stamp', full_name='monitoring.IncludeKpiRequest.time_stamp', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), + name='sampling_duration_s', full_name='monitoring.MonitorKpiRequest.sampling_duration_s', index=1, + number=2, 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='kpi_value', full_name='monitoring.IncludeKpiRequest.kpi_value', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, + name='sampling_interval_s', full_name='monitoring.MonitorKpiRequest.sampling_interval_s', index=2, + number=3, 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), @@ -253,8 +129,8 @@ _INCLUDEKPIREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=395, - serialized_end=510, + serialized_start=292, + serialized_end=404, ) @@ -285,8 +161,8 @@ _KPIID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=512, - serialized_end=550, + serialized_start=406, + serialized_end=444, ) @@ -313,33 +189,12 @@ _KPI = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='kpiDescription', full_name='monitoring.Kpi.kpiDescription', 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='kpi_value', full_name='monitoring.Kpi.kpi_value', index=3, + name='kpi_value', full_name='monitoring.Kpi.kpi_value', index=2, number=4, 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, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='kpi_sample_type', full_name='monitoring.Kpi.kpi_sample_type', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=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='device_id', full_name='monitoring.Kpi.device_id', index=5, - number=6, 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, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -352,8 +207,8 @@ _KPI = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=553, - serialized_end=767, + serialized_start=446, + serialized_end=546, ) @@ -410,8 +265,8 @@ _KPIVALUE = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[]), ], - serialized_start=769, - serialized_end=866, + serialized_start=548, + serialized_end=645, ) @@ -424,7 +279,7 @@ _KPILIST = _descriptor.Descriptor( create_key=_descriptor._internal_create_key, fields=[ _descriptor.FieldDescriptor( - name='kpiList', full_name='monitoring.KpiList.kpiList', index=0, + name='kpi_list', full_name='monitoring.KpiList.kpi_list', 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, @@ -442,21 +297,18 @@ _KPILIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=868, - serialized_end=911, + serialized_start=647, + serialized_end=691, ) -_CREATEKPIREQUEST.fields_by_name['device_id'].message_type = context__pb2._DEVICEID -_CREATEKPIREQUEST.fields_by_name['kpi_sample_type'].enum_type = _KPISAMPLETYPE +_KPIDESCRIPTOR.fields_by_name['kpi_sample_type'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE +_KPIDESCRIPTOR.fields_by_name['device_id'].message_type = context__pb2._DEVICEID +_KPIDESCRIPTOR.fields_by_name['endpoint_id'].message_type = context__pb2._ENDPOINTID +_KPIDESCRIPTOR.fields_by_name['service_id'].message_type = context__pb2._SERVICEID _MONITORKPIREQUEST.fields_by_name['kpi_id'].message_type = _KPIID -_MONITORDEVICEKPIREQUEST.fields_by_name['kpi'].message_type = _KPI -_INCLUDEKPIREQUEST.fields_by_name['kpi_id'].message_type = _KPIID -_INCLUDEKPIREQUEST.fields_by_name['kpi_value'].message_type = _KPIVALUE _KPIID.fields_by_name['kpi_id'].message_type = context__pb2._UUID _KPI.fields_by_name['kpi_id'].message_type = _KPIID _KPI.fields_by_name['kpi_value'].message_type = _KPIVALUE -_KPI.fields_by_name['kpi_sample_type'].enum_type = _KPISAMPLETYPE -_KPI.fields_by_name['device_id'].message_type = context__pb2._DEVICEID _KPIVALUE.oneofs_by_name['value'].fields.append( _KPIVALUE.fields_by_name['intVal']) _KPIVALUE.fields_by_name['intVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] @@ -469,24 +321,21 @@ _KPIVALUE.fields_by_name['stringVal'].containing_oneof = _KPIVALUE.oneofs_by_nam _KPIVALUE.oneofs_by_name['value'].fields.append( _KPIVALUE.fields_by_name['boolVal']) _KPIVALUE.fields_by_name['boolVal'].containing_oneof = _KPIVALUE.oneofs_by_name['value'] -_KPILIST.fields_by_name['kpiList'].message_type = _KPI -DESCRIPTOR.message_types_by_name['CreateKpiRequest'] = _CREATEKPIREQUEST +_KPILIST.fields_by_name['kpi_list'].message_type = _KPI +DESCRIPTOR.message_types_by_name['KpiDescriptor'] = _KPIDESCRIPTOR DESCRIPTOR.message_types_by_name['MonitorKpiRequest'] = _MONITORKPIREQUEST -DESCRIPTOR.message_types_by_name['MonitorDeviceKpiRequest'] = _MONITORDEVICEKPIREQUEST -DESCRIPTOR.message_types_by_name['IncludeKpiRequest'] = _INCLUDEKPIREQUEST DESCRIPTOR.message_types_by_name['KpiId'] = _KPIID DESCRIPTOR.message_types_by_name['Kpi'] = _KPI DESCRIPTOR.message_types_by_name['KpiValue'] = _KPIVALUE DESCRIPTOR.message_types_by_name['KpiList'] = _KPILIST -DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) -CreateKpiRequest = _reflection.GeneratedProtocolMessageType('CreateKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _CREATEKPIREQUEST, +KpiDescriptor = _reflection.GeneratedProtocolMessageType('KpiDescriptor', (_message.Message,), { + 'DESCRIPTOR' : _KPIDESCRIPTOR, '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.CreateKpiRequest) + # @@protoc_insertion_point(class_scope:monitoring.KpiDescriptor) }) -_sym_db.RegisterMessage(CreateKpiRequest) +_sym_db.RegisterMessage(KpiDescriptor) MonitorKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorKpiRequest', (_message.Message,), { 'DESCRIPTOR' : _MONITORKPIREQUEST, @@ -495,20 +344,6 @@ MonitorKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorKpiRequest' }) _sym_db.RegisterMessage(MonitorKpiRequest) -MonitorDeviceKpiRequest = _reflection.GeneratedProtocolMessageType('MonitorDeviceKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _MONITORDEVICEKPIREQUEST, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.MonitorDeviceKpiRequest) - }) -_sym_db.RegisterMessage(MonitorDeviceKpiRequest) - -IncludeKpiRequest = _reflection.GeneratedProtocolMessageType('IncludeKpiRequest', (_message.Message,), { - 'DESCRIPTOR' : _INCLUDEKPIREQUEST, - '__module__' : 'monitoring_pb2' - # @@protoc_insertion_point(class_scope:monitoring.IncludeKpiRequest) - }) -_sym_db.RegisterMessage(IncludeKpiRequest) - KpiId = _reflection.GeneratedProtocolMessageType('KpiId', (_message.Message,), { 'DESCRIPTOR' : _KPIID, '__module__' : 'monitoring_pb2' @@ -546,45 +381,45 @@ _MONITORINGSERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=1036, - serialized_end=1431, + serialized_start=694, + serialized_end=1065, methods=[ _descriptor.MethodDescriptor( name='CreateKpi', full_name='monitoring.MonitoringService.CreateKpi', index=0, containing_service=None, - input_type=_CREATEKPIREQUEST, + input_type=_KPIDESCRIPTOR, output_type=_KPIID, serialized_options=None, create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( - name='IncludeKpi', - full_name='monitoring.MonitoringService.IncludeKpi', + name='GetKpiDescriptor', + full_name='monitoring.MonitoringService.GetKpiDescriptor', index=1, containing_service=None, - input_type=_INCLUDEKPIREQUEST, - output_type=context__pb2._EMPTY, + input_type=_KPIID, + output_type=_KPIDESCRIPTOR, serialized_options=None, create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( - name='MonitorKpi', - full_name='monitoring.MonitoringService.MonitorKpi', + name='IncludeKpi', + full_name='monitoring.MonitoringService.IncludeKpi', index=2, containing_service=None, - input_type=_MONITORKPIREQUEST, + input_type=_KPI, output_type=context__pb2._EMPTY, serialized_options=None, create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( - name='MonitorDeviceKpi', - full_name='monitoring.MonitoringService.MonitorDeviceKpi', + name='MonitorKpi', + full_name='monitoring.MonitoringService.MonitorKpi', index=3, containing_service=None, - input_type=_MONITORDEVICEKPIREQUEST, + input_type=_MONITORKPIREQUEST, output_type=context__pb2._EMPTY, serialized_options=None, create_key=_descriptor._internal_create_key, diff --git a/src/monitoring/proto/monitoring_pb2_grpc.py b/src/monitoring/proto/monitoring_pb2_grpc.py index 2063dc0f3accaaed4d0a511faeceb53519626fd2..36c6835938af46b34b37f673bb6d4a1374a57cf0 100644 --- a/src/monitoring/proto/monitoring_pb2_grpc.py +++ b/src/monitoring/proto/monitoring_pb2_grpc.py @@ -17,12 +17,17 @@ class MonitoringServiceStub(object): """ self.CreateKpi = channel.unary_unary( '/monitoring.MonitoringService/CreateKpi', - request_serializer=monitoring__pb2.CreateKpiRequest.SerializeToString, + request_serializer=monitoring__pb2.KpiDescriptor.SerializeToString, response_deserializer=monitoring__pb2.KpiId.FromString, ) + self.GetKpiDescriptor = channel.unary_unary( + '/monitoring.MonitoringService/GetKpiDescriptor', + request_serializer=monitoring__pb2.KpiId.SerializeToString, + response_deserializer=monitoring__pb2.KpiDescriptor.FromString, + ) self.IncludeKpi = channel.unary_unary( '/monitoring.MonitoringService/IncludeKpi', - request_serializer=monitoring__pb2.IncludeKpiRequest.SerializeToString, + request_serializer=monitoring__pb2.Kpi.SerializeToString, response_deserializer=context__pb2.Empty.FromString, ) self.MonitorKpi = channel.unary_unary( @@ -30,11 +35,6 @@ class MonitoringServiceStub(object): request_serializer=monitoring__pb2.MonitorKpiRequest.SerializeToString, response_deserializer=context__pb2.Empty.FromString, ) - self.MonitorDeviceKpi = channel.unary_unary( - '/monitoring.MonitoringService/MonitorDeviceKpi', - request_serializer=monitoring__pb2.MonitorDeviceKpiRequest.SerializeToString, - response_deserializer=context__pb2.Empty.FromString, - ) self.GetStreamKpi = channel.unary_stream( '/monitoring.MonitoringService/GetStreamKpi', request_serializer=monitoring__pb2.KpiId.SerializeToString, @@ -51,25 +51,24 @@ class MonitoringServiceServicer(object): """Missing associated documentation comment in .proto file.""" def CreateKpi(self, request, context): - """Old RPCs: - """ + """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 IncludeKpi(self, request, context): + def GetKpiDescriptor(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 MonitorKpi(self, request, context): + def IncludeKpi(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 MonitorDeviceKpi(self, request, context): + def MonitorKpi(self, request, context): """Missing associated documentation comment in .proto file.""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -92,12 +91,17 @@ def add_MonitoringServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'CreateKpi': grpc.unary_unary_rpc_method_handler( servicer.CreateKpi, - request_deserializer=monitoring__pb2.CreateKpiRequest.FromString, + request_deserializer=monitoring__pb2.KpiDescriptor.FromString, response_serializer=monitoring__pb2.KpiId.SerializeToString, ), + 'GetKpiDescriptor': grpc.unary_unary_rpc_method_handler( + servicer.GetKpiDescriptor, + request_deserializer=monitoring__pb2.KpiId.FromString, + response_serializer=monitoring__pb2.KpiDescriptor.SerializeToString, + ), 'IncludeKpi': grpc.unary_unary_rpc_method_handler( servicer.IncludeKpi, - request_deserializer=monitoring__pb2.IncludeKpiRequest.FromString, + request_deserializer=monitoring__pb2.Kpi.FromString, response_serializer=context__pb2.Empty.SerializeToString, ), 'MonitorKpi': grpc.unary_unary_rpc_method_handler( @@ -105,11 +109,6 @@ def add_MonitoringServiceServicer_to_server(servicer, server): request_deserializer=monitoring__pb2.MonitorKpiRequest.FromString, response_serializer=context__pb2.Empty.SerializeToString, ), - 'MonitorDeviceKpi': grpc.unary_unary_rpc_method_handler( - servicer.MonitorDeviceKpi, - request_deserializer=monitoring__pb2.MonitorDeviceKpiRequest.FromString, - response_serializer=context__pb2.Empty.SerializeToString, - ), 'GetStreamKpi': grpc.unary_stream_rpc_method_handler( servicer.GetStreamKpi, request_deserializer=monitoring__pb2.KpiId.FromString, @@ -142,13 +141,13 @@ class MonitoringService(object): timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/CreateKpi', - monitoring__pb2.CreateKpiRequest.SerializeToString, + monitoring__pb2.KpiDescriptor.SerializeToString, monitoring__pb2.KpiId.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def IncludeKpi(request, + def GetKpiDescriptor(request, target, options=(), channel_credentials=None, @@ -158,14 +157,14 @@ class MonitoringService(object): wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/IncludeKpi', - monitoring__pb2.IncludeKpiRequest.SerializeToString, - context__pb2.Empty.FromString, + return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/GetKpiDescriptor', + monitoring__pb2.KpiId.SerializeToString, + monitoring__pb2.KpiDescriptor.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def MonitorKpi(request, + def IncludeKpi(request, target, options=(), channel_credentials=None, @@ -175,14 +174,14 @@ class MonitoringService(object): wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/MonitorKpi', - monitoring__pb2.MonitorKpiRequest.SerializeToString, + return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/IncludeKpi', + monitoring__pb2.Kpi.SerializeToString, context__pb2.Empty.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def MonitorDeviceKpi(request, + def MonitorKpi(request, target, options=(), channel_credentials=None, @@ -192,8 +191,8 @@ class MonitoringService(object): wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/MonitorDeviceKpi', - monitoring__pb2.MonitorDeviceKpiRequest.SerializeToString, + return grpc.experimental.unary_unary(request, target, '/monitoring.MonitoringService/MonitorKpi', + monitoring__pb2.MonitorKpiRequest.SerializeToString, context__pb2.Empty.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/monitoring/service/EventTools.py b/src/monitoring/service/EventTools.py new file mode 100644 index 0000000000000000000000000000000000000000..c54c5f57b7e45c9a71ea07e5b1f84b68334f86fa --- /dev/null +++ b/src/monitoring/service/EventTools.py @@ -0,0 +1,80 @@ +import threading +from queue import Queue + +import grpc + +from common.rpc_method_wrapper.ServiceExceptions import ServiceException +from context.client.ContextClient import ContextClient +from context.proto import kpi_sample_types_pb2 +from context.proto.context_pb2 import Empty, EventTypeEnum + +from common.logger import getJSONLogger +from monitoring.client.monitoring_client import MonitoringClient +from monitoring.proto import monitoring_pb2 + +LOGGER = getJSONLogger('monitoringservice-server') +LOGGER.setLevel('DEBUG') + +class EventsDeviceCollector: + def __init__(self, context_client_grpc : ContextClient, monitoring_client_grpc : MonitoringClient) -> None: # pylint: disable=redefined-outer-name + self._events_queue = Queue() + + self._device_stream = context_client_grpc.GetDeviceEvents(Empty()) + self._context_client = context_client_grpc + self._monitoring_client = monitoring_client_grpc + + self._device_thread = threading.Thread(target=self._collect, args=(self._device_stream ,), daemon=False) + + def _collect(self, events_stream) -> None: + try: + for event in events_stream: + self._events_queue.put_nowait(event) + except grpc.RpcError as e: + if e.code() != grpc.StatusCode.CANCELLED: # pylint: disable=no-member + raise # pragma: no cover + + def start(self): + self._device_thread.start() + + def get_event(self, block : bool = True, timeout : float = 0.1): + return self._events_queue.get(block=block, timeout=timeout) + + def stop(self): + + self._device_stream.cancel() + + self._device_thread.join() + + def listen_events(self): + LOGGER.info('getting Kpi by KpiID') + qsize = self._events_queue.qsize() + try: + kpi_id_list = [] + if qsize > 0: + for i in range(qsize): + print("Queue size: "+str(qsize)) + event = self.get_event(block=True) + if event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE: + device = self._context_client.GetDevice(event.device_id) + print("Endpoints value: " + str(len(device.device_endpoints))) + for j,end_point in enumerate(device.device_endpoints): + + # for k,rule in enumerate(device.device_config.config_rules): + kpi_descriptor = monitoring_pb2.KpiDescriptor() + + kpi_descriptor.kpi_description = device.device_type + kpi_descriptor.kpi_sample_type = kpi_sample_types_pb2.KpiSampleType.PACKETS_TRANSMITTED + kpi_descriptor.device_id.CopyFrom(device.device_id) + kpi_descriptor.endpoint_id.CopyFrom(end_point.endpoint_id) + kpi_descriptor.service_id.service_uuid.uuid = "SERV"+str(i+1) + + kpi_id = self._monitoring_client.CreateKpi(kpi_descriptor) + kpi_id_list.append(kpi_id) + + return kpi_id_list + + except ServiceException as e: + LOGGER.exception('ListenEvents exception') + + except Exception as e: # pragma: no cover + LOGGER.exception('ListenEvents exception') diff --git a/src/monitoring/service/influx_tools.py b/src/monitoring/service/InfluxTools.py similarity index 77% rename from src/monitoring/service/influx_tools.py rename to src/monitoring/service/InfluxTools.py index eca09b8cb1a04acadb8b2fb1a4db21da110ee9e8..df0cf01b2adddff4bcd0410d12505ed65c24e145 100644 --- a/src/monitoring/service/influx_tools.py +++ b/src/monitoring/service/InfluxTools.py @@ -4,14 +4,16 @@ class Influx(): def __init__(self, host, port, username, password, database): self.client = InfluxDBClient(host=host, port=port, username=username, password=password, database=database) - def write_KPI(self,time,kpi_id,device_id,kpi_sample_type,kpi_value): + def write_KPI(self,time,kpi_id,kpi_sample_type,device_id,endpoint_id,service_id,kpi_value): data = [{ "measurement": "samples", "time": time, "tags": { "kpi_id" : kpi_id, + "kpi_sample_type": kpi_sample_type, "device_id" : device_id, - "kpi_sample_type": kpi_sample_type + "endpoint_id" : endpoint_id, + "service_id" : service_id }, "fields": { "kpi_value": kpi_value @@ -26,3 +28,6 @@ class Influx(): points = results.get_points(tags={'kpi_id' : '1','device_id': '1', 'kpi_sample_type': '101'}) for point in points: print("Time: %s, Value: %i" % (point['time'], point['kpi_value'])) + + return points + diff --git a/src/monitoring/service/MonitoringService.py b/src/monitoring/service/MonitoringService.py index 08a3c81b542f6001140c38c9d9b9ae7bddb32190..665ce44f7e87ca73a92dfd6123ed3aa8935f0e92 100644 --- a/src/monitoring/service/MonitoringService.py +++ b/src/monitoring/service/MonitoringService.py @@ -2,14 +2,13 @@ from concurrent import futures import grpc -from monitoring.proto import monitoring_pb2_grpc from monitoring.service.MonitoringServiceServicerImpl import MonitoringServiceServicerImpl from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD +from monitoring.proto.monitoring_pb2_grpc import add_MonitoringServiceServicer_to_server from grpc_health.v1 import health from grpc_health.v1 import health_pb2 from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server -from monitoring.proto.monitoring_pb2_grpc import add_MonitoringServiceServicer_to_server from common.logger import getJSONLogger LOGGER = getJSONLogger('monitoringservice-server') diff --git a/src/monitoring/service/MonitoringServiceServicerImpl.py b/src/monitoring/service/MonitoringServiceServicerImpl.py index 1747e3a2b819442e2d221fdfca493d609ced70f4..3f5513bd4e0664137657e70803c5638437d6de31 100644 --- a/src/monitoring/service/MonitoringServiceServicerImpl.py +++ b/src/monitoring/service/MonitoringServiceServicerImpl.py @@ -1,18 +1,25 @@ -import os +import os,grpc -from monitoring.proto import context_pb2 -from monitoring.service import sqlite_tools, influx_tools +from prometheus_client import Summary +from prometheus_client import Counter +from monitoring.service import SqliteTools, InfluxTools from monitoring.proto import monitoring_pb2 from monitoring.proto import monitoring_pb2_grpc +from common.rpc_method_wrapper.ServiceExceptions import ServiceException from common.logger import getJSONLogger + +from context.proto import context_pb2 + + +from device.Config import GRPC_SERVICE_PORT +from device.client.DeviceClient import DeviceClient +from device.proto import device_pb2 + LOGGER = getJSONLogger('monitoringservice-server') LOGGER.setLevel('DEBUG') -from prometheus_client import start_http_server, Summary -from prometheus_client import Counter, Gauge - MONITORING_GETINSTANTKPI_REQUEST_TIME = Summary('monitoring_getinstantkpi_processing_seconds', 'Time spent processing monitoring instant kpi request') MONITORING_INCLUDEKPI_COUNTER = Counter('monitoring_includekpi_counter', 'Monitoring include kpi request counter') @@ -21,97 +28,135 @@ INFLUXDB_USER = os.environ.get("INFLUXDB_USER") INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD") INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE") + class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceServicer): def __init__(self): LOGGER.info('Init monitoringService') # Init sqlite monitoring db - self.sql_db = sqlite_tools.SQLite('monitoring.db') + self.sql_db = SqliteTools.SQLite('monitoring.db') # Create influx_db client - self.influx_db = influx_tools.Influx(INFLUXDB_HOSTNAME,"8086",INFLUXDB_USER,INFLUXDB_PASSWORD,INFLUXDB_DATABASE) + self.influx_db = InfluxTools.Influx(INFLUXDB_HOSTNAME,"8086",INFLUXDB_USER,INFLUXDB_PASSWORD,INFLUXDB_DATABASE) # CreateKpi (CreateKpiRequest) returns (KpiId) {} - def CreateKpi(self, request : monitoring_pb2.CreateKpiRequest, context) -> monitoring_pb2.KpiId : + def CreateKpi(self, request : monitoring_pb2.KpiDescriptor, grpc_context : grpc.ServicerContext) -> monitoring_pb2.KpiId : + # CREATEKPI_COUNTER_STARTED.inc() LOGGER.info('CreateKpi') - - # Here the code to create a sqlite query to crete a KPI and return a KpiID - kpi_id = monitoring_pb2.KpiId() - - kpi_description = request.kpiDescription - kpi_device_id = request.device_id.device_id.uuid - kpi_sample_type = request.kpi_sample_type - - data = self.sql_db.insert_KPI(kpi_description, kpi_device_id, kpi_sample_type) - kpi_id.kpi_id.uuid = str(data) - - return kpi_id + try: + # Here the code to create a sqlite query to crete a KPI and return a KpiID + kpi_id = monitoring_pb2.KpiId() + + kpi_description = request.kpi_description + kpi_sample_type = request.kpi_sample_type + kpi_device_id = request.device_id.device_uuid.uuid + kpi_endpoint_id = request.endpoint_id.endpoint_uuid.uuid + kpi_service_id = request.service_id.service_uuid.uuid + + data = self.sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id) + + kpi_id.kpi_id.uuid = str(data) + + # CREATEKPI_COUNTER_COMPLETED.inc() + return kpi_id + except ServiceException as e: + LOGGER.exception('CreateKpi exception') + # CREATEKPI_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: # pragma: no cover + LOGGER.exception('CreateKpi exception') + # CREATEKPI_COUNTER_FAILED.inc() + grpc_context.abort(grpc.StatusCode.INTERNAL, str(e)) # rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {} - def MonitorKpi ( self, request : monitoring_pb2.MonitorKpiRequest, context) -> context_pb2.Empty: + def MonitorKpi ( self, request : monitoring_pb2.MonitorKpiRequest, grpc_context : grpc.ServicerContext) -> context_pb2.Empty: LOGGER.info('MonitorKpi') + try: + # Creates the request to send to the device service + monitor_device_request = device_pb2.MonitoringSettings() - # Creates the request to send to the device service - monitor_device_request = monitoring_pb2.MonitorDeviceKpiRequest() - kpi = self.get_Kpi(request.kpi_id) - - monitor_device_request.kpi.kpi_id.kpi_id.uuid = kpi.kpi_id.kpi_id.uuid - monitor_device_request.connexion_time_s = request.connexion_time_s - monitor_device_request.sample_rate_ms = request.sample_rate_ms - - self.MonitorDeviceKpi(monitor_device_request,context) - - return context_pb2.Empty() - - # rpc MonitorDeviceKpi(MonitorDeviceKpiRequest) returns(context.Empty) {} - def MonitorDeviceKpi ( self, request : monitoring_pb2.MonitorDeviceKpiRequest, context) -> context_pb2.Empty: + kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context) - # Some code device to perform its actions + monitor_device_request.kpi_descriptor.CopyFrom(kpiDescriptor) + monitor_device_request.kpi_id.kpi_id.uuid = request.kpi_id.kpi_id.uuid + monitor_device_request.sampling_duration_s = request.sampling_duration_s + monitor_device_request.sampling_interval_s = request.sampling_interval_s - LOGGER.info('MonitorDeviceKpi') + deviceClient = DeviceClient(address="localhost", port=GRPC_SERVICE_PORT ) # instantiate the client + # deviceClient.MonitorDeviceKpi(monitor_device_request) - # Notify device about monitoring (device client to add) + return context_pb2.Empty() + except ServiceException as e: + LOGGER.exception('MonitorKpi exception') + # CREATEKPI_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: # pragma: no cover + LOGGER.exception('MonitorKpi exception') + # CREATEKPI_COUNTER_FAILED.inc() - return context_pb2.Empty() # rpc IncludeKpi(IncludeKpiRequest) returns(context.Empty) {} - def IncludeKpi(self, request : monitoring_pb2.IncludeKpiRequest, context) -> context_pb2.Empty: + def IncludeKpi(self, request : monitoring_pb2.Kpi, grpc_context : grpc.ServicerContext) -> context_pb2.Empty: LOGGER.info('IncludeKpi') - kpi = self.get_Kpi(request.kpi_id) - time_stamp = request.time_stamp - kpi_value = request.kpi_value.intVal + try: + kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context) - # Build the structure to be included as point in the influxDB - self.influx_db.write_KPI(time_stamp,kpi.kpi_id.kpi_id.uuid,kpi.device_id.device_id.uuid,kpi.kpi_sample_type,kpi_value) + kpiSampleType = kpiDescriptor.kpi_sample_type + kpiId = request.kpi_id.kpi_id.uuid + deviceId = kpiDescriptor.device_id.device_uuid.uuid + endpointId = kpiDescriptor.endpoint_id.endpoint_uuid.uuid + serviceId = kpiDescriptor.service_id.service_uuid.uuid + time_stamp = request.timestamp + kpi_value = request.kpi_value.intVal - self.influx_db.read_KPI_points() + # Build the structure to be included as point in the influxDB + self.influx_db.write_KPI(time_stamp,kpiId,kpiSampleType,deviceId,endpointId,serviceId,kpi_value) - return context_pb2.Empty() + self.influx_db.read_KPI_points() + return context_pb2.Empty() + except ServiceException as e: + LOGGER.exception('IncludeKpi exception') + # CREATEKPI_COUNTER_FAILED.inc() + grpc_context.abort(e.code, e.details) + except Exception as e: # pragma: no cover + LOGGER.exception('IncludeKpi exception') + # CREATEKPI_COUNTER_FAILED.inc() - def GetStreamKpi ( self, request, context): + def GetStreamKpi ( self, request, grpc_context : grpc.ServicerContext): # receives monitoring.KpiId returns stream monitoring.Kpi LOGGER.info('GetStreamKpi') yield monitoring_pb2.Kpi() @MONITORING_GETINSTANTKPI_REQUEST_TIME.time() - def GetInstantKpi ( self, request, context): + def GetInstantKpi ( self, request, grpc_context : grpc.ServicerContext): # receives monitoring.KpiId returns monitoring.Kpi LOGGER.info('GetInstantKpi') return monitoring_pb2.Kpi() - def get_Kpi(self, kpiId): + + def GetKpiDescriptor(self, request : monitoring_pb2.KpiId, grpc_context : grpc.ServicerContext) -> monitoring_pb2.KpiDescriptor: LOGGER.info('getting Kpi by KpiID') + try: + kpi_db = self.sql_db.get_KPI(int(request.kpi_id.uuid)) + + kpiDescriptor = monitoring_pb2.KpiDescriptor() + + kpiDescriptor.kpi_description = kpi_db[1] + kpiDescriptor.kpi_sample_type = kpi_db[2] + kpiDescriptor.device_id.device_uuid.uuid = str(kpi_db[3]) + kpiDescriptor.endpoint_id.endpoint_uuid.uuid = str(kpi_db[4]) + kpiDescriptor.service_id.service_uuid.uuid = str(kpi_db[5]) + + return kpiDescriptor + except ServiceException as e: + LOGGER.exception('GetKpiDescriptor exception') + grpc_context.abort(e.code, e.details) - kpi_db = self.sql_db.get_KPI(int(kpiId.kpi_id.uuid)) + except Exception as e: # pragma: no cover + LOGGER.exception('GetKpiDescriptor exception') - kpi = monitoring_pb2.Kpi() - kpi.kpi_id.kpi_id.uuid = str(kpi_db[0]) - kpi.kpiDescription = kpi_db[1] - kpi.device_id.device_id.uuid = kpi_db[2] - kpi.kpi_sample_type = kpi_db[3] - return kpi \ No newline at end of file diff --git a/src/monitoring/service/sqlite_tools.py b/src/monitoring/service/SqliteTools.py similarity index 74% rename from src/monitoring/service/sqlite_tools.py rename to src/monitoring/service/SqliteTools.py index 87437e7bef648990ad8dce95bbdc427b5eae9746..d03d6699b5ff29bc4bad4bd087cb6c0a965e397f 100644 --- a/src/monitoring/service/sqlite_tools.py +++ b/src/monitoring/service/SqliteTools.py @@ -6,18 +6,20 @@ class SQLite(): self.client.execute(""" CREATE TABLE IF NOT EXISTS KPI( kpi_id INTEGER PRIMARY KEY AUTOINCREMENT, - kpiDescription TEXT, + kpi_description TEXT, + kpi_sample_type INTEGER, device_id INTEGER, - kpi_sample_type INTEGER + endpoint_id INTEGER, + service_id INTEGER ); """) - def insert_KPI(self,kpiDescription,device_id,kpi_sample_type): + def insert_KPI(self,kpi_description,kpi_sample_type,device_id,endpoint_id,service_id ): c = self.client.cursor() - c.execute("SELECT kpi_id FROM KPI WHERE device_id is ? AND kpi_sample_type is ?",(device_id,kpi_sample_type)) + c.execute("SELECT kpi_id FROM KPI WHERE device_id is ? AND kpi_sample_type is ? AND endpoint_id is ?",(device_id,kpi_sample_type,endpoint_id)) data=c.fetchone() if data is None: - c.execute("INSERT INTO KPI (kpiDescription, device_id,kpi_sample_type) VALUES (?,?,?)", (kpiDescription,device_id,kpi_sample_type)) + c.execute("INSERT INTO KPI (kpi_description,kpi_sample_type,device_id,endpoint_id,service_id) VALUES (?,?,?,?,?)", (kpi_description,kpi_sample_type,device_id,endpoint_id,service_id)) self.client.commit() return c.lastrowid else: @@ -52,4 +54,5 @@ class SQLite(): def get_KPIS(self): data = self.client.execute("SELECT * FROM KPI") for row in data: - print(row) \ No newline at end of file + print(row) + return data.fetchall() \ No newline at end of file diff --git a/src/monitoring/service/__main__.py b/src/monitoring/service/__main__.py index 4d001e286ae568198b9b47497d633cade524b864..ea189e1c905b07f92ef3e9cd100763eb7dffa08f 100644 --- a/src/monitoring/service/__main__.py +++ b/src/monitoring/service/__main__.py @@ -1,9 +1,13 @@ import logging, os, signal, sys, threading import time +from context.client.ContextClient import ContextClient from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT from common.logger import getJSONLogger +from monitoring.client.monitoring_client import MonitoringClient +from monitoring.proto import monitoring_pb2 +from monitoring.service.EventTools import EventsDeviceCollector from monitoring.service.MonitoringService import MonitoringService LOGGER = getJSONLogger('monitoringservice-server') @@ -16,9 +20,40 @@ logger = None def signal_handler(signal, frame): global terminate, logger - logger.warning('Terminate signal received') + LOGGER.warning('Terminate signal received') terminate.set() +def start_monitoring(): + LOGGER.info('Start Monitoring...') + context_client_grpc = ContextClient(address='localhost', port='2020') + monitoring_client = MonitoringClient(server='localhost', port='7070') # instantiate the client + + while True: + if terminate.is_set(): + LOGGER.warning("Stopping execution...") + + break + + # Start Listening Events + events_collector = EventsDeviceCollector(context_client_grpc, monitoring_client) + events_collector.start() + + list_new_kpi_ids = events_collector.listen_events() + + # Monitor Kpis + if bool(list_new_kpi_ids): + for kpi_id in list_new_kpi_ids: + # Create Monitor Kpi Requests + monitor_kpi_request = monitoring_pb2.MonitorKpiRequest() + monitor_kpi_request.kpi_id.CopyFrom(kpi_id) + monitor_kpi_request.sampling_duration_s = 120 + monitor_kpi_request.sampling_interval_s = 5 + + # MonitorKpi(monitor_kpi_request) + + + + def main(): global terminate, logger @@ -42,6 +77,8 @@ def main(): grpc_service = MonitoringService(port=service_port, max_workers=max_workers, grace_period=grace_period) grpc_service.start() + # start_monitoring() + # Wait for Ctrl+C or termination signal while not terminate.wait(timeout=0.1): pass diff --git a/src/monitoring/tests/test_monitoring.py b/src/monitoring/tests/test_monitoring.py deleted file mode 100644 index 8252c2253f11ca7e3f3ec620628f5285821a4228..0000000000000000000000000000000000000000 --- a/src/monitoring/tests/test_monitoring.py +++ /dev/null @@ -1,159 +0,0 @@ -import logging, os -import pytest - -from monitoring.proto import context_pb2 -from monitoring.proto import monitoring_pb2 -from monitoring.client.monitoring_client import MonitoringClient -from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT -from monitoring.service.MonitoringService import MonitoringService - -LOGGER = logging.getLogger(__name__) -LOGGER.setLevel(logging.DEBUG) - -SERVER_ADDRESS = '127.0.0.1' -LISTEN_ADDRESS = '[::]' -PORT = 7070 - -########################### -# Tests Setup -########################### - -# This fixture will be requested by test cases and last during testing session -@pytest.fixture(scope='session') -def monitoring_service(): - LOGGER.warning('monitoring_service begin') - - service_port = GRPC_SERVICE_PORT - max_workers = GRPC_MAX_WORKERS - grace_period = GRPC_GRACE_PERIOD - - LOGGER.info('Initializing MonitoringService...') - grpc_service = MonitoringService(port=service_port, max_workers=max_workers, grace_period=grace_period) - server = grpc_service.start() - - # yield the server, when test finishes, execution will resume to stop it - LOGGER.warning('monitoring_service yielding') - yield server - - LOGGER.info('Terminating MonitoringService...') - grpc_service.stop() - -# This fixture will be requested by test cases and last during testing session. -# The client requires the server, so client fixture has the server as dependency. -@pytest.fixture(scope='session') -def monitoring_client(monitoring_service): - LOGGER.warning('monitoring_client begin') - client = MonitoringClient(server=SERVER_ADDRESS, port=PORT) # instantiate the client - LOGGER.warning('monitoring_client returning') - return client - -# This fixture will be requested by test cases and last during testing session. -@pytest.fixture(scope='session') -def kpi(): - LOGGER.warning('test_include_kpi begin') - # form request - kpi = monitoring_pb2.Kpi() - kpi.kpi_id.kpi_id.uuid = 'KPIID0000' # pylint: disable=maybe-no-member - kpi.kpiDescription = 'KPI Desc' - return kpi - -@pytest.fixture(scope='session') -def kpi_id(): - LOGGER.warning('test_include_kpi begin') - - # form request - kpi_id = monitoring_pb2.KpiId() - kpi_id.kpi_id.uuid = 'KPIID0000' - - return kpi_id - -@pytest.fixture(scope='session') -def create_kpi_request(): - LOGGER.warning('test_include_kpi begin') - - create_kpi_request = monitoring_pb2.CreateKpiRequest() - create_kpi_request.device_id.device_id.uuid = 'DEV1' # pylint: disable=maybe-no-member - create_kpi_request.kpiDescription = 'KPI Description' - create_kpi_request.kpi_sample_type = monitoring_pb2.KpiSampleType.PACKETS_TRANSMITTED - - return create_kpi_request - -@pytest.fixture(scope='session') -def monitor_kpi_request(): - LOGGER.warning('test_monitor_kpi begin') - - monitor_kpi_request = monitoring_pb2.MonitorKpiRequest() - monitor_kpi_request.kpi_id.kpi_id.uuid = str(1) - monitor_kpi_request.connexion_time_s = 120 - monitor_kpi_request.sample_rate_ms = 5 - - return monitor_kpi_request - -@pytest.fixture(scope='session') -def monitor_device_kpi_request(): - LOGGER.warning('test_monitor_kpi begin') - - monitor_device_kpi_request = monitoring_pb2.MonitorDeviceKpiRequest() - monitor_device_kpi_request.connexion_time_s = 120 - monitor_device_kpi_request.sample_rate_ms = 5 - - return monitor_device_kpi_request - -@pytest.fixture(scope='session') -def include_kpi_request(): - LOGGER.warning('test_include_kpi begin') - - include_kpi_request = monitoring_pb2.IncludeKpiRequest() - include_kpi_request.kpi_id.kpi_id.uuid = str(1) - include_kpi_request.time_stamp = "2021-10-12T13:14:42Z" - include_kpi_request.kpi_value.intVal = 500 - - return include_kpi_request - -########################### -# Tests Implementation -########################### - -# Test case that makes use of client fixture to test server's CreateKpi method -def test_create_kpi(monitoring_client,create_kpi_request): - # make call to server - LOGGER.warning('test_create_kpi requesting') - response = monitoring_client.CreateKpi(create_kpi_request) - LOGGER.debug(str(response)) - assert isinstance(response, monitoring_pb2.KpiId) - -# Test case that makes use of client fixture to test server's MonitorKpi method -def test_monitor_kpi(monitoring_client,monitor_kpi_request): - LOGGER.warning('test_monitor_kpi begin') - response = monitoring_client.MonitorKpi(monitor_kpi_request) - LOGGER.debug(str(response)) - assert isinstance(response, context_pb2.Empty) - -# Test case that makes use of client fixture to test server's MonitorDeviceKpi method -def test_monitor_device_kpi(monitoring_client,monitor_device_kpi_request): - LOGGER.warning('test_monitor_device_kpi begin') - response = monitoring_client.MonitorDeviceKpi(monitor_device_kpi_request) - LOGGER.debug(str(response)) - assert isinstance(response, context_pb2.Empty) - -# Test case that makes use of client fixture to test server's IncludeKpi method -def test_include_kpi(monitoring_client,include_kpi_request): - # make call to server - LOGGER.warning('test_include_kpi requesting') - response = monitoring_client.IncludeKpi(include_kpi_request) - LOGGER.debug(str(response)) - assert isinstance(response, context_pb2.Empty) - -# Test case that makes use of client fixture to test server's GetStreamKpi method -def test_getstream_kpi(monitoring_client,kpi): - LOGGER.warning('test_getstream_kpi begin') - response = monitoring_client.GetStreamKpi(kpi) - LOGGER.debug(str(response)) - #assert isinstance(response, monitoring_pb2.Kpi) - -# Test case that makes use of client fixture to test server's GetInstantKpi method -def test_getinstant_kpi(monitoring_client,kpi_id): - LOGGER.warning('test_getinstant_kpi begin') - response = monitoring_client.GetInstantKpi(kpi_id) - LOGGER.debug(str(response)) - assert isinstance(response, monitoring_pb2.Kpi) diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py new file mode 100644 index 0000000000000000000000000000000000000000..84f9f6e4178ea55628d604e304eb2a54dd66c81e --- /dev/null +++ b/src/monitoring/tests/test_unitary.py @@ -0,0 +1,388 @@ +import logging, grpc +import os +import sqlite3 + +import pytest +from typing import Tuple + +from monitoring.proto import context_pb2, kpi_sample_types_pb2 +from monitoring.proto import monitoring_pb2 +from monitoring.client.monitoring_client import MonitoringClient +from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD +from monitoring.service import SqliteTools, InfluxTools +from monitoring.service.MonitoringService import MonitoringService +from monitoring.service.EventTools import EventsDeviceCollector + +from common.orm.Database import Database +from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum +from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum +from common.message_broker.MessageBroker import MessageBroker + +from context.Config import GRPC_SERVICE_PORT as grpc_port_context, GRPC_MAX_WORKERS as grpc_workers_context, GRPC_GRACE_PERIOD as grpc_grace_context +from context.client.ContextClient import ContextClient +from context.service.grpc_server.ContextService import ContextService +from context.service.Populate import populate +from context.proto.context_pb2 import EventTypeEnum, DeviceEvent, Device +from context.tests.example_objects import (DEVICE1, DEVICE1_UUID) + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +########################### +# Tests Setup +########################### + +SERVER_ADDRESS = '127.0.0.1' +LISTEN_ADDRESS = '[::]' +GRPC_PORT_MONITORING = 7070 + +GRPC_PORT_CONTEXT = 10000 + grpc_port_context # avoid privileged ports + +SCENARIOS = [ # comment/uncomment scenarios to activate/deactivate them in the test unit + ('all_inmemory', DatabaseBackendEnum.INMEMORY, {}, MessageBrokerBackendEnum.INMEMORY, {} ), +] + +INFLUXDB_HOSTNAME = os.environ.get("INFLUXDB_HOSTNAME") +INFLUXDB_USER = os.environ.get("INFLUXDB_USER") +INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD") +INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE") + +@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS) +def context_db_mb(request) -> Tuple[Database, MessageBroker]: + name,db_backend,db_settings,mb_backend,mb_settings = request.param + msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...' + LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings))) + _database = Database(get_database_backend(backend=db_backend, **db_settings)) + _message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings)) + yield _database, _message_broker + _message_broker.terminate() + +@pytest.fixture(scope='session') +def context_service_grpc(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name + database = context_db_mb[0] + database.clear_all() + _service = ContextService( + database, context_db_mb[1], port=GRPC_PORT_CONTEXT, max_workers=grpc_workers_context, + grace_period=grpc_grace_context) + _service.start() + yield _service + _service.stop() + +@pytest.fixture(scope='session') +def context_client_grpc(context_service_grpc : ContextService): # pylint: disable=redefined-outer-name + _client = ContextClient(address='localhost', port=GRPC_PORT_CONTEXT) + yield _client + _client.close() + + +# This fixture will be requested by test cases and last during testing session +@pytest.fixture(scope='session') +def monitoring_service(): + LOGGER.warning('monitoring_service begin') + + service_port = GRPC_SERVICE_PORT + max_workers = GRPC_MAX_WORKERS + grace_period = GRPC_GRACE_PERIOD + + LOGGER.info('Initializing MonitoringService...') + grpc_service = MonitoringService(port=service_port, max_workers=max_workers, grace_period=grace_period) + server = grpc_service.start() + + # yield the server, when test finishes, execution will resume to stop it + LOGGER.warning('monitoring_service yielding') + yield server + + LOGGER.info('Terminating MonitoringService...') + grpc_service.stop() + +# This fixture will be requested by test cases and last during testing session. +# The client requires the server, so client fixture has the server as dependency. +@pytest.fixture(scope='session') +def monitoring_client(monitoring_service): + LOGGER.warning('monitoring_client begin') + client = MonitoringClient(server=SERVER_ADDRESS, port=GRPC_PORT_MONITORING) # instantiate the client + LOGGER.warning('monitoring_client returning') + return client + +# This fixture will be requested by test cases and last during testing session. +@pytest.fixture(scope='session') +def kpi(): + LOGGER.warning('test_include_kpi begin') + # form request + kpi = monitoring_pb2.Kpi() + kpi.kpi_id.kpi_id.uuid = 'KPIID0000' + kpi.kpiDescription = 'KPI Desc' + return kpi + +@pytest.fixture(scope='session') +def kpi_id(): + LOGGER.warning('test_include_kpi begin') + + # form request + kpi_id = monitoring_pb2.KpiId() + kpi_id.kpi_id.uuid = str(1) + + return kpi_id + +@pytest.fixture(scope='session') +def sql_db(): + sql_db = SqliteTools.SQLite('monitoring.db') + return sql_db + +@pytest.fixture(scope='session') +def influx_db(): + influx_db = InfluxTools.Influx(INFLUXDB_HOSTNAME, "8086", INFLUXDB_USER, INFLUXDB_PASSWORD, INFLUXDB_DATABASE) + return influx_db + +@pytest.fixture(scope='session') +def create_kpi_request(): + LOGGER.warning('test_include_kpi begin') + + create_kpi_request = monitoring_pb2.KpiDescriptor() + create_kpi_request.kpi_description = 'KPI Description Test' + create_kpi_request.kpi_sample_type = kpi_sample_types_pb2.KpiSampleType.PACKETS_TRANSMITTED + create_kpi_request.device_id.device_uuid.uuid = 'DEV1' # pylint: disable=maybe-no-member + create_kpi_request.service_id.service_uuid.uuid = "SERV1" + create_kpi_request.endpoint_id.endpoint_uuid.uuid = "END1" + + return create_kpi_request + +@pytest.fixture(scope='session') +def monitor_kpi_request(): + LOGGER.warning('test_monitor_kpi begin') + + monitor_kpi_request = monitoring_pb2.MonitorKpiRequest() + monitor_kpi_request.kpi_id.kpi_id.uuid = str(1) + monitor_kpi_request.sampling_duration_s = 120 + monitor_kpi_request.sampling_interval_s = 5 + + return monitor_kpi_request + + +@pytest.fixture(scope='session') +def include_kpi_request(): + LOGGER.warning('test_include_kpi begin') + + include_kpi_request = monitoring_pb2.Kpi() + include_kpi_request.kpi_id.kpi_id.uuid = str(1) + include_kpi_request.timestamp = "2021-10-12T13:14:42Z" + include_kpi_request.kpi_value.intVal = 500 + + return include_kpi_request + +########################### +# Tests Implementation +########################### + +# Test case that makes use of client fixture to test server's CreateKpi method +def test_create_kpi(monitoring_client,create_kpi_request): + # make call to server + LOGGER.warning('test_create_kpi requesting') + response = monitoring_client.CreateKpi(create_kpi_request) + LOGGER.debug(str(response)) + assert isinstance(response, monitoring_pb2.KpiId) + +# Test case that makes use of client fixture to test server's MonitorKpi method +def test_monitor_kpi(monitoring_client,monitor_kpi_request): + LOGGER.warning('test_monitor_kpi begin') + response = monitoring_client.MonitorKpi(monitor_kpi_request) + LOGGER.debug(str(response)) + assert isinstance(response, context_pb2.Empty) + + +# Test case that makes use of client fixture to test server's IncludeKpi method +def test_include_kpi(monitoring_client,include_kpi_request): + # make call to server + LOGGER.warning('test_include_kpi requesting') + response = monitoring_client.IncludeKpi(include_kpi_request) + LOGGER.debug(str(response)) + assert isinstance(response, context_pb2.Empty) + +# Test case that makes use of client fixture to test server's GetStreamKpi method +def test_get_stream_kpi(monitoring_client,include_kpi_request): + LOGGER.warning('test_getstream_kpi begin') + response = monitoring_client.GetStreamKpi(kpi) + LOGGER.debug(str(response)) + #assert isinstance(response, monitoring_pb2.Kpi) + +# Test case that makes use of client fixture to test server's GetInstantKpi method +def test_get_instant_kpi(monitoring_client,kpi_id): + LOGGER.warning('test_getinstant_kpi begin') + response = monitoring_client.GetInstantKpi(kpi_id) + LOGGER.debug(str(response)) + assert isinstance(response, monitoring_pb2.Kpi) + +# Test case that makes use of client fixture to test server's GetInstantKpi method +def test_get_kpidescritor_kpi(monitoring_client,kpi_id): + LOGGER.warning('test_getkpidescritor_kpi begin') + response = monitoring_client.GetKpiDescriptor(kpi_id) + LOGGER.debug(str(response)) + assert isinstance(response, monitoring_pb2.KpiDescriptor) + +def test_sqlitedb_tools_insert_kpi(sql_db, create_kpi_request): + LOGGER.warning('test_sqlitedb_tools_insert_kpi begin') + + kpi_description = create_kpi_request.kpi_description + kpi_sample_type = create_kpi_request.kpi_sample_type + kpi_device_id = create_kpi_request.device_id.device_uuid.uuid + kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid + kpi_service_id = create_kpi_request.service_id.service_uuid.uuid + + response = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id) + assert isinstance(response, int) + +def test_sqlitedb_tools_get_kpi(sql_db, create_kpi_request): + LOGGER.warning('test_sqlitedb_tools_get_kpi begin') + + kpi_description = create_kpi_request.kpi_description + kpi_sample_type = create_kpi_request.kpi_sample_type + kpi_device_id = create_kpi_request.device_id.device_uuid.uuid + kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid + kpi_service_id = create_kpi_request.service_id.service_uuid.uuid + + kpi_id = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id) + + response = sql_db.get_KPI(kpi_id) + assert isinstance(response, tuple) + +def test_sqlitedb_tools_get_kpis(sql_db): + LOGGER.warning('test_sqlitedb_tools_get_kpis begin') + response = sql_db.get_KPIS() + assert isinstance(response, list) + +def test_sqlitedb_tools_delete_kpi(sql_db, create_kpi_request): + LOGGER.warning('test_sqlitedb_tools_get_kpi begin') + + response = sql_db.delete_KPI("DEV1",kpi_sample_types_pb2.KpiSampleType.PACKETS_TRANSMITTED) + + if response == False: + kpi_description = create_kpi_request.kpi_description + kpi_sample_type = create_kpi_request.kpi_sample_type + kpi_device_id = create_kpi_request.device_id.device_uuid.uuid + kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid + kpi_service_id = create_kpi_request.service_id.service_uuid.uuid + + sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id) + response = sql_db.delete_KPI("DEV1", kpi_sample_types_pb2.KpiSampleType.PACKETS_TRANSMITTED) + + assert response == True + +def test_sqlitedb_tools_delete_kpid_id(sql_db, create_kpi_request): + LOGGER.warning('test_sqlitedb_tools_delete_kpid_id begin') + + response = sql_db.delete_kpid_id(1) + + if response == False: + kpi_description = create_kpi_request.kpi_description + kpi_sample_type = create_kpi_request.kpi_sample_type + kpi_device_id = create_kpi_request.device_id.device_uuid.uuid + kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid + kpi_service_id = create_kpi_request.service_id.service_uuid.uuid + + kpi_id = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id) + response = sql_db.delete_kpid_id(kpi_id) + + assert response == True + + +def test_influxdb_tools_write_kpi(influx_db): + LOGGER.warning('test_influxdb_tools_write_kpi begin') + +def test_influxdb_tools_read_kpi_points(influx_db): + LOGGER.warning('test_influxdb_tools_read_kpi_points begin') + + +def test_events_tools(context_client_grpc: ContextClient, # pylint: disable=redefined-outer-name + monitoring_client : MonitoringClient, + context_db_mb: Tuple[Database, MessageBroker]): + LOGGER.warning('test_get_device_events begin') + + context_database = context_db_mb[0] + + # ----- Clean the database ----------------------------------------------------------------------------------------- + context_database.clear_all() + + # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- + events_collector = EventsDeviceCollector(context_client_grpc, monitoring_client) + events_collector.start() + + # # ----- Dump state of database before create the object ------------------------------------------------------------ + db_entries = context_database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 0 + + populate('localhost', GRPC_PORT_CONTEXT) # place this call in the appropriate line, according to your tests + + # ----- Update the object ------------------------------------------------------------------------------------------ + response = context_client_grpc.SetDevice(Device(**DEVICE1)) + assert response.device_uuid.uuid == DEVICE1_UUID + + events_collector.stop() + + +def test_get_device_events(context_client_grpc: ContextClient, # pylint: disable=redefined-outer-name + monitoring_client : MonitoringClient, + context_db_mb: Tuple[Database, MessageBroker]): + + LOGGER.warning('test_get_device_events begin') + + context_database = context_db_mb[0] + + # ----- Clean the database ----------------------------------------------------------------------------------------- + context_database.clear_all() + + # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- + events_collector = EventsDeviceCollector(context_client_grpc,monitoring_client) + events_collector.start() + + # # ----- Dump state of database before create the object ------------------------------------------------------------ + db_entries = context_database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 0 + + populate('localhost', GRPC_PORT_CONTEXT) # place this call in the appropriate line, according to your tests + + # ----- Check create event ----------------------------------------------------------------------------------------- + event = events_collector.get_event(block=True) + + assert isinstance(event, DeviceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert event.device_id.device_uuid.uuid == DEVICE1_UUID + + events_collector.stop() + +def test_listen_events(monitoring_client: MonitoringClient, + context_client_grpc: ContextClient, # pylint: disable=redefined-outer-name + context_db_mb: Tuple[Database, MessageBroker]): + + LOGGER.warning('test_listen_events begin') + + context_database = context_db_mb[0] + + # ----- Clean the database ----------------------------------------------------------------------------------------- + context_database.clear_all() + + # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- + events_collector = EventsDeviceCollector(context_client_grpc,monitoring_client) + events_collector.start() + + # # ----- Dump state of database before create the object ------------------------------------------------------------ + db_entries = context_database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 0 + + populate('localhost', GRPC_PORT_CONTEXT) # place this call in the appropriate line, according to your tests + + kpi_id_list = events_collector.listen_events() + + assert bool(kpi_id_list) == True +