Loading proto/context.proto +16 −9 Original line number Diff line number Diff line Loading @@ -494,6 +494,12 @@ message ConfigRule { // ----- Constraint ---------------------------------------------------------------------------------------------------- enum ConstraintActionEnum { CONSTRAINTACTION_UNDEFINED = 0; CONSTRAINTACTION_SET = 1; CONSTRAINTACTION_DELETE = 2; } message Constraint_Custom { string constraint_type = 1; string constraint_value = 2; Loading Loading @@ -564,16 +570,17 @@ message Constraint_Exclusions { } message Constraint { ConstraintActionEnum action = 1; oneof constraint { Constraint_Custom custom = 1; Constraint_Schedule schedule = 2; Constraint_EndPointLocation endpoint_location = 3; Constraint_EndPointPriority endpoint_priority = 4; Constraint_SLA_Capacity sla_capacity = 5; Constraint_SLA_Latency sla_latency = 6; Constraint_SLA_Availability sla_availability = 7; Constraint_SLA_Isolation_level sla_isolation = 8; Constraint_Exclusions exclusions = 9; Constraint_Custom custom = 2; Constraint_Schedule schedule = 3; Constraint_EndPointLocation endpoint_location = 4; Constraint_EndPointPriority endpoint_priority = 5; Constraint_SLA_Capacity sla_capacity = 6; Constraint_SLA_Latency sla_latency = 7; Constraint_SLA_Availability sla_availability = 8; Constraint_SLA_Isolation_level sla_isolation = 9; Constraint_Exclusions exclusions = 10; } } Loading src/common/tests/MockServicerImpl_Context.py +98 −5 Original line number Diff line number Diff line Loading @@ -13,15 +13,15 @@ # limitations under the License. import grpc, json, logging from typing import Any, Dict, Iterator, List from typing import Any, Dict, Iterator, List, Set from common.proto.context_pb2 import ( Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId, ContextIdList, ContextList, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, Device, DeviceEvent, DeviceFilter, DeviceId, DeviceIdList, DeviceList, Empty, EventTypeEnum, Link, LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceId, SliceIdList, SliceList, Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList) from common.proto.context_pb2_grpc import ContextServiceServicer from common.tests.MockMessageBroker import ( Loading Loading @@ -68,10 +68,19 @@ def del_entry( del container[entry_uuid] return Empty() def select_entries(database : Dict[str, Dict[str, Any]], container_name : str, entry_uuids : Set[str]) -> List[Any]: if len(entry_uuids) == 0: return get_entries(database, container_name) container = get_container(database, container_name) return [ container[entry_uuid] for entry_uuid in sorted(container.keys()) if entry_uuid in entry_uuids ] class MockServicerImpl_Context(ContextServiceServicer): def __init__(self): LOGGER.info('[__init__] Creating Servicer...') self.database : Dict[str, Any] = {} self.database : Dict[str, Dict[str, Any]] = {} self.msg_broker = MockMessageBroker() LOGGER.info('[__init__] Servicer Created') Loading Loading @@ -210,6 +219,33 @@ class MockServicerImpl_Context(ContextServiceServicer): LOGGER.info('[GetDeviceEvents] request={:s}'.format(grpc_message_to_json_string(request))) for message in self.msg_broker.consume({TOPIC_DEVICE}): yield DeviceEvent(**json.loads(message.content)) def SelectDevice(self, request : DeviceFilter, context : grpc.ServicerContext) -> DeviceList: LOGGER.info('[SelectDevice] request={:s}'.format(grpc_message_to_json_string(request))) container_entry_uuids : Dict[str, Set[str]] = {} container_name = 'device' for device_id in request.device_ids.device_ids: device_uuid = device_id.device_uuid.uuid container_entry_uuids.setdefault(container_name, set()).add(device_uuid) exclude_endpoints = not request.include_endpoints exclude_config_rules = not request.include_config_rules exclude_components = not request.include_components devices = list() for container_name in sorted(container_entry_uuids.keys()): entry_uuids = container_entry_uuids[container_name] for device in select_entries(self.database, container_name, entry_uuids): reply_device = Device() reply_device.CopyFrom(device) if exclude_endpoints: del reply_device.device_endpoints [:] # pylint: disable=no-member if exclude_config_rules: del reply_device.device_config.config_rules[:] # pylint: disable=no-member if exclude_components: del reply_device.component[:] # pylint: disable=no-member devices.append(reply_device) reply = DeviceList(devices=devices) LOGGER.info('[SelectDevice] reply={:s}'.format(grpc_message_to_json_string(reply))) return reply # ----- Link ------------------------------------------------------------------------------------------------------- Loading Loading @@ -291,6 +327,37 @@ class MockServicerImpl_Context(ContextServiceServicer): LOGGER.info('[GetSliceEvents] request={:s}'.format(grpc_message_to_json_string(request))) for message in self.msg_broker.consume({TOPIC_SLICE}): yield SliceEvent(**json.loads(message.content)) def SelectSlice(self, request : SliceFilter, context : grpc.ServicerContext) -> SliceList: LOGGER.info('[SelectSlice] request={:s}'.format(grpc_message_to_json_string(request))) container_entry_uuids : Dict[str, Set[str]] = {} for slice_id in request.slice_ids.slice_ids: container_name = 'slice[{:s}]'.format(str(slice_id.context_id.context_uuid.uuid)) slice_uuid = slice_id.slice_uuid.uuid container_entry_uuids.setdefault(container_name, set()).add(slice_uuid) exclude_endpoint_ids = not request.include_endpoint_ids exclude_constraints = not request.include_constraints exclude_service_ids = not request.include_service_ids exclude_subslice_ids = not request.include_subslice_ids exclude_config_rules = not request.include_config_rules slices = list() for container_name in sorted(container_entry_uuids.keys()): entry_uuids = container_entry_uuids[container_name] for eslice in select_entries(self.database, container_name, entry_uuids): reply_slice = Slice() reply_slice.CopyFrom(eslice) if exclude_endpoint_ids: del reply_slice.service_endpoint_ids[:] # pylint: disable=no-member if exclude_constraints : del reply_slice.service_constraints[:] # pylint: disable=no-member if exclude_service_ids : del reply_slice.slice_service_ids[:] # pylint: disable=no-member if exclude_subslice_ids : del reply_slice.slice_subslice_ids[:] # pylint: disable=no-member if exclude_config_rules: del reply_slice.slice_config .config_rules[:] # pylint: disable=no-member slices.append(reply_slice) reply = SliceList(slices=slices) LOGGER.info('[SelectSlice] reply={:s}'.format(grpc_message_to_json_string(reply))) return reply # ----- Service ---------------------------------------------------------------------------------------------------- Loading Loading @@ -335,6 +402,32 @@ class MockServicerImpl_Context(ContextServiceServicer): LOGGER.info('[GetServiceEvents] request={:s}'.format(grpc_message_to_json_string(request))) for message in self.msg_broker.consume({TOPIC_SERVICE}): yield ServiceEvent(**json.loads(message.content)) def SelectService(self, request : ServiceFilter, context : grpc.ServicerContext) -> ServiceList: LOGGER.info('[SelectService] request={:s}'.format(grpc_message_to_json_string(request))) container_entry_uuids : Dict[str, Set[str]] = {} for service_id in request.service_ids.service_ids: container_name = 'service[{:s}]'.format(str(service_id.context_id.context_uuid.uuid)) service_uuid = service_id.service_uuid.uuid container_entry_uuids.setdefault(container_name, set()).add(service_uuid) exclude_endpoint_ids = not request.include_endpoint_ids exclude_constraints = not request.include_constraints exclude_config_rules = not request.include_config_rules services = list() for container_name in sorted(container_entry_uuids.keys()): entry_uuids = container_entry_uuids[container_name] for service in select_entries(self.database, container_name, entry_uuids): reply_service = Service() reply_service.CopyFrom(service) if exclude_endpoint_ids: del reply_service.service_endpoint_ids[:] # pylint: disable=no-member if exclude_constraints : del reply_service.service_constraints[:] # pylint: disable=no-member if exclude_config_rules: del reply_service.service_config.config_rules[:] # pylint: disable=no-member services.append(reply_service) reply = ServiceList(services=services) LOGGER.info('[SelectService] reply={:s}'.format(grpc_message_to_json_string(reply))) return reply # ----- Connection ------------------------------------------------------------------------------------------------- Loading src/common/tools/object_factory/EndPoint.py +2 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ def json_endpoint_ids( def json_endpoint( device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None, kpi_sample_types : List[int] = [] kpi_sample_types : List[int] = [], location : Optional[Dict] = None ): result = { Loading @@ -38,6 +38,7 @@ def json_endpoint( 'endpoint_type': endpoint_type, } if len(kpi_sample_types) > 0: result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types) if location: result['endpoint_location'] = copy.deepcopy(location) return result def json_endpoints( Loading src/common/tools/object_factory/Location.py 0 → 100644 +30 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import copy from typing import Dict, Optional def json_gps_position(latitude : float, longitude : float): return {'latitude': latitude, 'longitude': longitude} def json_location(region : Optional[str] = None, gps_position : Optional[Dict] = None): if not region and not gps_position: raise Exception('One of "region" or "gps_position" arguments must be filled') if region: result = {'region': region} else: result = {'gps_position': copy.deepcopy(gps_position)} return result src/compute/service/rest_server/nbi_plugins/debug_api/Resources.py +0 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ from .Tools import ( format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link_id, grpc_policy_rule_id, grpc_service_id, grpc_slice_id, grpc_topology_id) class _Resource(Resource): def __init__(self) -> None: super().__init__() Loading Loading
proto/context.proto +16 −9 Original line number Diff line number Diff line Loading @@ -494,6 +494,12 @@ message ConfigRule { // ----- Constraint ---------------------------------------------------------------------------------------------------- enum ConstraintActionEnum { CONSTRAINTACTION_UNDEFINED = 0; CONSTRAINTACTION_SET = 1; CONSTRAINTACTION_DELETE = 2; } message Constraint_Custom { string constraint_type = 1; string constraint_value = 2; Loading Loading @@ -564,16 +570,17 @@ message Constraint_Exclusions { } message Constraint { ConstraintActionEnum action = 1; oneof constraint { Constraint_Custom custom = 1; Constraint_Schedule schedule = 2; Constraint_EndPointLocation endpoint_location = 3; Constraint_EndPointPriority endpoint_priority = 4; Constraint_SLA_Capacity sla_capacity = 5; Constraint_SLA_Latency sla_latency = 6; Constraint_SLA_Availability sla_availability = 7; Constraint_SLA_Isolation_level sla_isolation = 8; Constraint_Exclusions exclusions = 9; Constraint_Custom custom = 2; Constraint_Schedule schedule = 3; Constraint_EndPointLocation endpoint_location = 4; Constraint_EndPointPriority endpoint_priority = 5; Constraint_SLA_Capacity sla_capacity = 6; Constraint_SLA_Latency sla_latency = 7; Constraint_SLA_Availability sla_availability = 8; Constraint_SLA_Isolation_level sla_isolation = 9; Constraint_Exclusions exclusions = 10; } } Loading
src/common/tests/MockServicerImpl_Context.py +98 −5 Original line number Diff line number Diff line Loading @@ -13,15 +13,15 @@ # limitations under the License. import grpc, json, logging from typing import Any, Dict, Iterator, List from typing import Any, Dict, Iterator, List, Set from common.proto.context_pb2 import ( Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId, ContextIdList, ContextList, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, Device, DeviceEvent, DeviceFilter, DeviceId, DeviceIdList, DeviceList, Empty, EventTypeEnum, Link, LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceId, SliceIdList, SliceList, Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList) from common.proto.context_pb2_grpc import ContextServiceServicer from common.tests.MockMessageBroker import ( Loading Loading @@ -68,10 +68,19 @@ def del_entry( del container[entry_uuid] return Empty() def select_entries(database : Dict[str, Dict[str, Any]], container_name : str, entry_uuids : Set[str]) -> List[Any]: if len(entry_uuids) == 0: return get_entries(database, container_name) container = get_container(database, container_name) return [ container[entry_uuid] for entry_uuid in sorted(container.keys()) if entry_uuid in entry_uuids ] class MockServicerImpl_Context(ContextServiceServicer): def __init__(self): LOGGER.info('[__init__] Creating Servicer...') self.database : Dict[str, Any] = {} self.database : Dict[str, Dict[str, Any]] = {} self.msg_broker = MockMessageBroker() LOGGER.info('[__init__] Servicer Created') Loading Loading @@ -210,6 +219,33 @@ class MockServicerImpl_Context(ContextServiceServicer): LOGGER.info('[GetDeviceEvents] request={:s}'.format(grpc_message_to_json_string(request))) for message in self.msg_broker.consume({TOPIC_DEVICE}): yield DeviceEvent(**json.loads(message.content)) def SelectDevice(self, request : DeviceFilter, context : grpc.ServicerContext) -> DeviceList: LOGGER.info('[SelectDevice] request={:s}'.format(grpc_message_to_json_string(request))) container_entry_uuids : Dict[str, Set[str]] = {} container_name = 'device' for device_id in request.device_ids.device_ids: device_uuid = device_id.device_uuid.uuid container_entry_uuids.setdefault(container_name, set()).add(device_uuid) exclude_endpoints = not request.include_endpoints exclude_config_rules = not request.include_config_rules exclude_components = not request.include_components devices = list() for container_name in sorted(container_entry_uuids.keys()): entry_uuids = container_entry_uuids[container_name] for device in select_entries(self.database, container_name, entry_uuids): reply_device = Device() reply_device.CopyFrom(device) if exclude_endpoints: del reply_device.device_endpoints [:] # pylint: disable=no-member if exclude_config_rules: del reply_device.device_config.config_rules[:] # pylint: disable=no-member if exclude_components: del reply_device.component[:] # pylint: disable=no-member devices.append(reply_device) reply = DeviceList(devices=devices) LOGGER.info('[SelectDevice] reply={:s}'.format(grpc_message_to_json_string(reply))) return reply # ----- Link ------------------------------------------------------------------------------------------------------- Loading Loading @@ -291,6 +327,37 @@ class MockServicerImpl_Context(ContextServiceServicer): LOGGER.info('[GetSliceEvents] request={:s}'.format(grpc_message_to_json_string(request))) for message in self.msg_broker.consume({TOPIC_SLICE}): yield SliceEvent(**json.loads(message.content)) def SelectSlice(self, request : SliceFilter, context : grpc.ServicerContext) -> SliceList: LOGGER.info('[SelectSlice] request={:s}'.format(grpc_message_to_json_string(request))) container_entry_uuids : Dict[str, Set[str]] = {} for slice_id in request.slice_ids.slice_ids: container_name = 'slice[{:s}]'.format(str(slice_id.context_id.context_uuid.uuid)) slice_uuid = slice_id.slice_uuid.uuid container_entry_uuids.setdefault(container_name, set()).add(slice_uuid) exclude_endpoint_ids = not request.include_endpoint_ids exclude_constraints = not request.include_constraints exclude_service_ids = not request.include_service_ids exclude_subslice_ids = not request.include_subslice_ids exclude_config_rules = not request.include_config_rules slices = list() for container_name in sorted(container_entry_uuids.keys()): entry_uuids = container_entry_uuids[container_name] for eslice in select_entries(self.database, container_name, entry_uuids): reply_slice = Slice() reply_slice.CopyFrom(eslice) if exclude_endpoint_ids: del reply_slice.service_endpoint_ids[:] # pylint: disable=no-member if exclude_constraints : del reply_slice.service_constraints[:] # pylint: disable=no-member if exclude_service_ids : del reply_slice.slice_service_ids[:] # pylint: disable=no-member if exclude_subslice_ids : del reply_slice.slice_subslice_ids[:] # pylint: disable=no-member if exclude_config_rules: del reply_slice.slice_config .config_rules[:] # pylint: disable=no-member slices.append(reply_slice) reply = SliceList(slices=slices) LOGGER.info('[SelectSlice] reply={:s}'.format(grpc_message_to_json_string(reply))) return reply # ----- Service ---------------------------------------------------------------------------------------------------- Loading Loading @@ -335,6 +402,32 @@ class MockServicerImpl_Context(ContextServiceServicer): LOGGER.info('[GetServiceEvents] request={:s}'.format(grpc_message_to_json_string(request))) for message in self.msg_broker.consume({TOPIC_SERVICE}): yield ServiceEvent(**json.loads(message.content)) def SelectService(self, request : ServiceFilter, context : grpc.ServicerContext) -> ServiceList: LOGGER.info('[SelectService] request={:s}'.format(grpc_message_to_json_string(request))) container_entry_uuids : Dict[str, Set[str]] = {} for service_id in request.service_ids.service_ids: container_name = 'service[{:s}]'.format(str(service_id.context_id.context_uuid.uuid)) service_uuid = service_id.service_uuid.uuid container_entry_uuids.setdefault(container_name, set()).add(service_uuid) exclude_endpoint_ids = not request.include_endpoint_ids exclude_constraints = not request.include_constraints exclude_config_rules = not request.include_config_rules services = list() for container_name in sorted(container_entry_uuids.keys()): entry_uuids = container_entry_uuids[container_name] for service in select_entries(self.database, container_name, entry_uuids): reply_service = Service() reply_service.CopyFrom(service) if exclude_endpoint_ids: del reply_service.service_endpoint_ids[:] # pylint: disable=no-member if exclude_constraints : del reply_service.service_constraints[:] # pylint: disable=no-member if exclude_config_rules: del reply_service.service_config.config_rules[:] # pylint: disable=no-member services.append(reply_service) reply = ServiceList(services=services) LOGGER.info('[SelectService] reply={:s}'.format(grpc_message_to_json_string(reply))) return reply # ----- Connection ------------------------------------------------------------------------------------------------- Loading
src/common/tools/object_factory/EndPoint.py +2 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ def json_endpoint_ids( def json_endpoint( device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None, kpi_sample_types : List[int] = [] kpi_sample_types : List[int] = [], location : Optional[Dict] = None ): result = { Loading @@ -38,6 +38,7 @@ def json_endpoint( 'endpoint_type': endpoint_type, } if len(kpi_sample_types) > 0: result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types) if location: result['endpoint_location'] = copy.deepcopy(location) return result def json_endpoints( Loading
src/common/tools/object_factory/Location.py 0 → 100644 +30 −0 Original line number Diff line number Diff line # Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import copy from typing import Dict, Optional def json_gps_position(latitude : float, longitude : float): return {'latitude': latitude, 'longitude': longitude} def json_location(region : Optional[str] = None, gps_position : Optional[Dict] = None): if not region and not gps_position: raise Exception('One of "region" or "gps_position" arguments must be filled') if region: result = {'region': region} else: result = {'gps_position': copy.deepcopy(gps_position)} return result
src/compute/service/rest_server/nbi_plugins/debug_api/Resources.py +0 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ from .Tools import ( format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link_id, grpc_policy_rule_id, grpc_service_id, grpc_slice_id, grpc_topology_id) class _Resource(Resource): def __init__(self) -> None: super().__init__() Loading