diff --git a/manifests/pathcompservice.yaml b/manifests/pathcompservice.yaml index 679552e2fbaf14ceb7e1a190f11adb6877efa386..d5939cb154443139be88d8e0ac23c281a3b18c4d 100644 --- a/manifests/pathcompservice.yaml +++ b/manifests/pathcompservice.yaml @@ -51,18 +51,18 @@ spec: - name: backend image: registry.gitlab.com/teraflow-h2020/controller/pathcomp-backend:latest imagePullPolicy: Always - readinessProbe: - httpGet: - path: /health - port: 8081 - initialDelaySeconds: 5 - timeoutSeconds: 5 - livenessProbe: - httpGet: - path: /health - port: 8081 - initialDelaySeconds: 5 - timeoutSeconds: 5 + #readinessProbe: + # httpGet: + # path: /health + # port: 8081 + # initialDelaySeconds: 5 + # timeoutSeconds: 5 + #livenessProbe: + # httpGet: + # path: /health + # port: 8081 + # initialDelaySeconds: 5 + # timeoutSeconds: 5 resources: requests: cpu: 250m diff --git a/src/common/tools/object_factory/Constraint.py b/src/common/tools/object_factory/Constraint.py index df290d4285330f1965608d710d9d48ca49131521..757531daf65b60c5f5b6c90ee67ef00488f91590 100644 --- a/src/common/tools/object_factory/Constraint.py +++ b/src/common/tools/object_factory/Constraint.py @@ -15,6 +15,19 @@ import json from typing import Any, Dict, Union -def json_constraint(constraint_type : str, constraint_value : Union[str, Dict[str, Any]]): +def json_constraint_custom(constraint_type : str, constraint_value : Union[str, Dict[str, Any]]) -> Dict: if not isinstance(constraint_value, str): constraint_value = json.dumps(constraint_value, sort_keys=True) return {'custom': {'constraint_type': constraint_type, 'constraint_value': constraint_value}} + +def json_constraint_endpoint_location_region(endpoint_id : Dict, region : str) -> Dict: + return {'endpoint_location': {'endpoint_id': endpoint_id, 'location': {'region': region}}} + +def json_constraint_endpoint_location_gps(endpoint_id : Dict, latitude : float, longitude : float) -> Dict: + gps_position = {'latitude': latitude, 'longitude': longitude} + return {'endpoint_location': {'endpoint_id': endpoint_id, 'location': {'gps_position': gps_position}}} + +def json_constraint_endpoint_priority(endpoint_id : Dict, priority : int) -> Dict: + return {'endpoint_priority': {'endpoint_id': endpoint_id, 'priority': priority}} + +def json_constraint_sla_availability(num_disjoint_paths : int, all_active : bool) -> Dict: + return {'sla_availability': {'num_disjoint_paths': num_disjoint_paths, 'all_active': all_active}} diff --git a/src/context/tests/Objects.py b/src/context/tests/Objects.py index 519a0093ac2733125487ed9daf0c61e0821910d5..da63ed6ea8329bc77e897c1f88d6ba04e8ffc79b 100644 --- a/src/context/tests/Objects.py +++ b/src/context/tests/Objects.py @@ -16,7 +16,7 @@ from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.object_factory.ConfigRule import json_config_rule_set from common.tools.object_factory.Connection import json_connection, json_connection_id -from common.tools.object_factory.Constraint import json_constraint +from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import json_device_id, json_device_packetrouter_disabled from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id @@ -129,8 +129,8 @@ SERVICE_R1_R2_EPIDS = [ json_endpoint_id(DEVICE_R2_ID, 'EP100', topology_id=TOPOLOGY_ID), ] SERVICE_R1_R2_CONST = [ - json_constraint('latency_ms', '15.2'), - json_constraint('jitter_us', '1.2'), + json_constraint_custom('latency_ms', '15.2'), + json_constraint_custom('jitter_us', '1.2'), ] SERVICE_R1_R2_RULES = [ json_config_rule_set('svc/rsrc1/value', 'value7'), @@ -149,8 +149,8 @@ SERVICE_R1_R3_EPIDS = [ json_endpoint_id(DEVICE_R3_ID, 'EP100', topology_id=TOPOLOGY_ID), ] SERVICE_R1_R3_CONST = [ - json_constraint('latency_ms', '5.8'), - json_constraint('jitter_us', '0.1'), + json_constraint_custom('latency_ms', '5.8'), + json_constraint_custom('jitter_us', '0.1'), ] SERVICE_R1_R3_RULES = [ json_config_rule_set('svc/rsrc1/value', 'value7'), @@ -169,8 +169,8 @@ SERVICE_R2_R3_EPIDS = [ json_endpoint_id(DEVICE_R3_ID, 'EP100', topology_id=TOPOLOGY_ID), ] SERVICE_R2_R3_CONST = [ - json_constraint('latency_ms', '23.1'), - json_constraint('jitter_us', '3.4'), + json_constraint_custom('latency_ms', '23.1'), + json_constraint_custom('jitter_us', '3.4'), ] SERVICE_R2_R3_RULES = [ json_config_rule_set('svc/rsrc1/value', 'value7'), diff --git a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py index c95f4e64a8660b437a1ae6721534c1c2f42f3303..48e951b1dbe01790e1ec44d2759c6079d52d0aab 100644 --- a/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py @@ -28,7 +28,7 @@ Service_Endpoints = Dict[Endpoint_Id, Endpoint_Details] Service_Details = Tuple[int, Service_Constraints, Service_Endpoints] Services_Details = Dict[Service_Id, Service_Details] -CUSTOM_CONSTRAINTS = {'bandwidth[gbps]', 'latency[ms]'} +CUSTOM_CONSTRAINTS = {'bandwidth[gbps]', 'latency[ms]', 'jitter[us]'} DUMP_EXECUTION_STEPS = False diff --git a/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py b/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py index 944a2d168e47f5329b4afd6103540ba76a0c5d01..d5f937fd207807ba650669ea9fb2395b2e21b164 100644 --- a/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py +++ b/src/pathcomp/frontend/service/algorithms/ShortestPathAlgorithm.py @@ -18,11 +18,9 @@ from ._Algorithm import _Algorithm class ShortestPathAlgorithm(_Algorithm): def __init__(self, algorithm : Algorithm_ShortestPath, class_name=__name__) -> None: super().__init__('SP', False, class_name=class_name) - self.k_paths = 1 def add_service_requests(self, requested_services) -> None: super().add_service_requests(requested_services) for service_request in self.service_list: service_request['algId' ] = self.algorithm_id service_request['syncPaths'] = self.sync_paths - service_request['kPaths' ] = self.k_paths diff --git a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py index 706906b36d02d3ac5d8bcf05f4ae8d2e1243a561..d24597c6beac4d4a27c7cb141c3349b862076f20 100644 --- a/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py +++ b/src/pathcomp/frontend/service/algorithms/tools/ComposeRequest.py @@ -12,18 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging from typing import Dict +from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID from common.proto.context_pb2 import Constraint, Device, EndPointId, Link, Service, ServiceId, TopologyId from common.tools.grpc.Tools import grpc_message_to_json_string from .Constants import CapacityUnit, LinkForwardingDirection, LinkPortDirection, TerminationDirection, TerminationState +LOGGER = logging.getLogger(__name__) + def compose_topology_id(topology_id : TopologyId) -> Dict: context_uuid = topology_id.context_id.context_uuid.uuid topology_uuid = topology_id.topology_uuid.uuid + + if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_UUID + if len(topology_uuid) == 0: topology_uuid = DEFAULT_TOPOLOGY_UUID + return {'contextId': context_uuid, 'topology_uuid': topology_uuid} def compose_service_id(service_id : ServiceId) -> Dict: context_uuid = service_id.context_id.context_uuid.uuid + + if len(context_uuid) == 0: context_uuid = DEFAULT_CONTEXT_UUID + service_uuid = service_id.service_uuid.uuid return {'contextId': context_uuid, 'service_uuid': service_uuid} @@ -54,9 +65,9 @@ def compose_latency_characteristics(fixed_latency_characteristic : str) -> Dict: def compose_constraint(constraint : Constraint) -> Dict: if constraint.WhichOneof('constraint') != 'custom': - MSG = 'Constraint({:s}) not supported' str_constraint = grpc_message_to_json_string(constraint) - raise NotImplementedError(MSG.format(str_constraint)) + LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint)) + return None constraint_type = constraint.custom.constraint_type constraint_value = constraint.custom.constraint_value return {'constraint_type': constraint_type, 'constraint_value': constraint_value} @@ -110,10 +121,10 @@ def compose_service(grpc_service : Service) -> Dict: for service_endpoint_id in grpc_service.service_endpoint_ids ] - constraints = [ + constraints = list(filter(lambda constraint: constraint is not None, [ compose_constraint(service_constraint) for service_constraint in grpc_service.service_constraints - ] + ])) return { 'serviceId': service_id, diff --git a/src/pathcomp/frontend/tests/Objects_A_B_C.py b/src/pathcomp/frontend/tests/Objects_A_B_C.py index 586911180bcb7379382b644cac1eb338a31bd522..510ebb6746ccb8d050d5eb6ea91ec6354f224459 100644 --- a/src/pathcomp/frontend/tests/Objects_A_B_C.py +++ b/src/pathcomp/frontend/tests/Objects_A_B_C.py @@ -13,7 +13,7 @@ # limitations under the License. from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID -from common.tools.object_factory.Constraint import json_constraint +from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Context import json_context, json_context_id from common.tools.object_factory.Device import json_device_emulated_packet_router_disabled, json_device_id from common.tools.object_factory.EndPoint import json_endpoints @@ -97,8 +97,8 @@ LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPO # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[ - json_constraint('bandwidth[gbps]', 10.0), - json_constraint('latency[ms]', 12.0), + json_constraint_custom('bandwidth[gbps]', 10.0), + json_constraint_custom('latency[ms]', 12.0), ]) # ----- Containers ----------------------------------------------------------------------------------------------------- diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py index edb468455ba4edf5ea63a545f2b1c78d0c2cad94..d40d76454078177fd5b61455d0445859512463f4 100644 --- a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py +++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py @@ -13,19 +13,36 @@ # limitations under the License. from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID -from common.tools.object_factory.Constraint import json_constraint +from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Context import json_context, json_context_id -from common.tools.object_factory.Device import json_device_emulated_packet_router_disabled, json_device_id +from common.tools.object_factory.Device import ( + json_device_emulated_connect_rules, json_device_emulated_datacenter_disabled, + json_device_emulated_packet_router_disabled, json_device_id) from common.tools.object_factory.EndPoint import json_endpoints from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned from common.tools.object_factory.Topology import json_topology, json_topology_id -def compose_device(device_uuid, endpoint_uuids, topology_id=None): +# if true, Device component is present and will infeer the endpoints from connect-rules +# if false, Device component is not present and device objects must contain preconfigured endpoints +ADD_CONNECT_RULES_TO_DEVICES = False + +def compose_router(device_uuid, endpoint_uuids, topology_id=None): + device_id = json_device_id(device_uuid) + r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids] + config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else [] + endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id) + j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints + device = json_device_emulated_packet_router_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints) + return device_id, endpoints, device + +def compose_datacenter(device_uuid, endpoint_uuids, topology_id=None): device_id = json_device_id(device_uuid) - endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids] - endpoints = json_endpoints(device_id, endpoints, topology_id=topology_id) - device = json_device_emulated_packet_router_disabled(device_uuid, endpoints=endpoints) + r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids] + config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else [] + endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id) + j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints + device = json_device_emulated_datacenter_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints) return device_id, endpoints, device def compose_link(endpoint_a, endpoint_z): @@ -78,20 +95,20 @@ TOPO_TN = json_topology(TOPO_TN_UUID, context_id=CONTEXT_ID) # ----- Devices -------------------------------------------------------------------------------------------------------- # DataCenters -DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_device('DC1-GW', ['eth1', 'eth2', 'int'], topology_id=TOPO_DC1_ID) -DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_device('DC2-GW', ['eth1', 'eth2', 'int'], topology_id=TOPO_DC2_ID) +DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_datacenter('DC1-GW', ['eth1', 'eth2', 'int']) +DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_datacenter('DC2-GW', ['eth1', 'eth2', 'int']) # CellSites -DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_device('CS1-GW1', ['1000', '100', '200'], topology_id=TOPO_CS1_ID) -DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_device('CS1-GW2', ['1000', '100', '200'], topology_id=TOPO_CS1_ID) -DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_device('CS2-GW1', ['1000', '100', '200'], topology_id=TOPO_CS2_ID) -DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_device('CS2-GW2', ['1000', '100', '200'], topology_id=TOPO_CS2_ID) +DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_router('CS1-GW1', ['10/1', '1/1', '1/2']) +DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_router('CS1-GW2', ['10/1', '1/1', '1/2']) +DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_router('CS2-GW1', ['10/1', '1/1', '1/2']) +DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_router('CS2-GW2', ['10/1', '1/1', '1/2']) # Transport Network -DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_device('TN-R1', ['100', '200', '1', '2', '3'], topology_id=TOPO_TN_ID) -DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_device('TN-R2', ['100', '200', '1', '2', '3'], topology_id=TOPO_TN_ID) -DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_device('TN-R3', ['100', '200', '1', '2', '3'], topology_id=TOPO_TN_ID) -DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_device('TN-R4', ['100', '200', '1', '2', '3'], topology_id=TOPO_TN_ID) +DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_router('TN-R1', ['1/1', '1/2', '2/1', '2/2', '2/3']) +DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_router('TN-R2', ['1/1', '1/2', '2/1', '2/2', '2/3']) +DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_router('TN-R3', ['1/1', '1/2', '2/1', '2/2', '2/3']) +DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_router('TN-R4', ['1/1', '1/2', '2/1', '2/2', '2/3']) # ----- Links ---------------------------------------------------------------------------------------------------------- @@ -122,32 +139,36 @@ LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4 # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[ - json_constraint('bandwidth[gbps]', 10.0), - json_constraint('latency[ms]', 12.0), + json_constraint_custom('bandwidth[gbps]', 10.0), + json_constraint_custom('latency[ms]', 12.0), ]) # ----- Containers ----------------------------------------------------------------------------------------------------- -CONTEXTS = [ CONTEXT] -TOPOLOGIES = [ TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN] +CONTEXTS = [ CONTEXT ] +TOPOLOGIES = [ TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN ] DEVICES = [ DEV_DC1GW, DEV_DC2GW, DEV_CS1GW1, DEV_CS1GW2, DEV_CS2GW1, DEV_CS2GW2, - DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4 ] + DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4, + ] LINKS = [ LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2, LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1, LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3, - LINK_TNR1_TNR2, LINK_TNR2_TNR3, LINK_TNR3_TNR4, LINK_TNR4_TNR1, LINK_TNR1_TNR3, LINK_TNR2_TNR4 ] + LINK_TNR1_TNR2, LINK_TNR2_TNR3, LINK_TNR3_TNR4, LINK_TNR4_TNR1, LINK_TNR1_TNR3, LINK_TNR2_TNR4, + ] SERVICES = [ SERVICE_DC1GW_DC2GW ] OBJECTS_PER_TOPOLOGY = [ (TOPO_ADMIN_ID, [ DEV_DC1GW_ID, DEV_DC2GW_ID, DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID, - DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID ], + DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, + ], [ LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID, LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID, LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID, LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, - LINK_TNR2_TNR4_ID ], + LINK_TNR2_TNR4_ID, + ], ), (TOPO_DC1_ID, [DEV_DC1GW_ID], @@ -162,7 +183,9 @@ OBJECTS_PER_TOPOLOGY = [ [DEV_CS2GW1_ID, DEV_CS2GW2_ID], []), (TOPO_TN_ID, - [DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID], - [LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, - LINK_TNR2_TNR4_ID]), + [ DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, + ], + [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, + LINK_TNR2_TNR4_ID, + ]), ] diff --git a/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py new file mode 100644 index 0000000000000000000000000000000000000000..a9b4a1512599ce4436b3498beb0b5ae4ebae92fb --- /dev/null +++ b/src/pathcomp/frontend/tests/Objects_DC_CSGW_TN_OLS.py @@ -0,0 +1,202 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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 uuid +from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID +from common.tools.object_factory.Constraint import json_constraint_custom +from common.tools.object_factory.Context import json_context, json_context_id +from common.tools.object_factory.Device import ( + json_device_emulated_connect_rules, json_device_emulated_datacenter_disabled, + json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled, json_device_id) +from common.tools.object_factory.EndPoint import json_endpoints +from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id +from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned +from common.tools.object_factory.Topology import json_topology, json_topology_id + +# if true, Device component is present and will infeer the endpoints from connect-rules +# if false, Device component is not present and device objects must contain preconfigured endpoints +ADD_CONNECT_RULES_TO_DEVICES = False + +def compose_router(device_uuid, endpoint_uuids, topology_id=None): + device_id = json_device_id(device_uuid) + r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids] + config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else [] + endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id) + j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints + device = json_device_emulated_packet_router_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints) + return device_id, endpoints, device + +def compose_ols(device_uuid, endpoint_uuids, topology_id=None): + device_id = json_device_id(device_uuid) + r_endpoints = [(endpoint_uuid, 'optical', []) for endpoint_uuid in endpoint_uuids] + config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else [] + endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id) + j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints + device = json_device_emulated_tapi_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints) + return device_id, endpoints, device + +def compose_datacenter(device_uuid, endpoint_uuids, topology_id=None): + device_id = json_device_id(device_uuid) + r_endpoints = [(endpoint_uuid, 'copper', []) for endpoint_uuid in endpoint_uuids] + config_rules = json_device_emulated_connect_rules(r_endpoints) if ADD_CONNECT_RULES_TO_DEVICES else [] + endpoints = json_endpoints(device_id, r_endpoints, topology_id=topology_id) + j_endpoints = [] if ADD_CONNECT_RULES_TO_DEVICES else endpoints + device = json_device_emulated_datacenter_disabled(device_uuid, config_rules=config_rules, endpoints=j_endpoints) + return device_id, endpoints, device + +def compose_link(endpoint_a, endpoint_z): + link_uuid = get_link_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id']) + link_id = json_link_id(link_uuid) + link = json_link(link_uuid, [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']]) + return link_id, link + +def compose_service(endpoint_a, endpoint_z, constraints=[]): + service_uuid = get_service_uuid(endpoint_a['endpoint_id'], endpoint_z['endpoint_id']) + endpoint_ids = [endpoint_a['endpoint_id'], endpoint_z['endpoint_id']] + service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints) + return service + +# ----- Context -------------------------------------------------------------------------------------------------------- +CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID) +CONTEXT = json_context(DEFAULT_CONTEXT_UUID) + +# ----- Domains -------------------------------------------------------------------------------------------------------- +# Overall network topology +TOPO_ADMIN_UUID = DEFAULT_TOPOLOGY_UUID +TOPO_ADMIN_ID = json_topology_id(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) +TOPO_ADMIN = json_topology(TOPO_ADMIN_UUID, context_id=CONTEXT_ID) + +# DataCenter #1 Network +TOPO_DC1_UUID = 'DC1' +TOPO_DC1_ID = json_topology_id(TOPO_DC1_UUID, context_id=CONTEXT_ID) +TOPO_DC1 = json_topology(TOPO_DC1_UUID, context_id=CONTEXT_ID) + +# DataCenter #2 Network +TOPO_DC2_UUID = 'DC2' +TOPO_DC2_ID = json_topology_id(TOPO_DC2_UUID, context_id=CONTEXT_ID) +TOPO_DC2 = json_topology(TOPO_DC2_UUID, context_id=CONTEXT_ID) + +# CellSite #1 Network +TOPO_CS1_UUID = 'CS1' +TOPO_CS1_ID = json_topology_id(TOPO_CS1_UUID, context_id=CONTEXT_ID) +TOPO_CS1 = json_topology(TOPO_CS1_UUID, context_id=CONTEXT_ID) + +# CellSite #2 Network +TOPO_CS2_UUID = 'CS2' +TOPO_CS2_ID = json_topology_id(TOPO_CS2_UUID, context_id=CONTEXT_ID) +TOPO_CS2 = json_topology(TOPO_CS2_UUID, context_id=CONTEXT_ID) + +# Transport Network Network +TOPO_TN_UUID = 'TN' +TOPO_TN_ID = json_topology_id(TOPO_TN_UUID, context_id=CONTEXT_ID) +TOPO_TN = json_topology(TOPO_TN_UUID, context_id=CONTEXT_ID) + + +# ----- Devices -------------------------------------------------------------------------------------------------------- +# DataCenters +DEV_DC1GW_ID, DEV_DC1GW_EPS, DEV_DC1GW = compose_datacenter('DC1-GW', ['eth1', 'eth2', 'int']) +DEV_DC2GW_ID, DEV_DC2GW_EPS, DEV_DC2GW = compose_datacenter('DC2-GW', ['eth1', 'eth2', 'int']) + +# CellSites +DEV_CS1GW1_ID, DEV_CS1GW1_EPS, DEV_CS1GW1 = compose_router('CS1-GW1', ['10/1', '1/1', '1/2']) +DEV_CS1GW2_ID, DEV_CS1GW2_EPS, DEV_CS1GW2 = compose_router('CS1-GW2', ['10/1', '1/1', '1/2']) +DEV_CS2GW1_ID, DEV_CS2GW1_EPS, DEV_CS2GW1 = compose_router('CS2-GW1', ['10/1', '1/1', '1/2']) +DEV_CS2GW2_ID, DEV_CS2GW2_EPS, DEV_CS2GW2 = compose_router('CS2-GW2', ['10/1', '1/1', '1/2']) + +# Transport Network +DEV_TNR1_ID, DEV_TNR1_EPS, DEV_TNR1 = compose_router('TN-R1', ['1/1', '1/2', '2/1']) +DEV_TNR2_ID, DEV_TNR2_EPS, DEV_TNR2 = compose_router('TN-R2', ['1/1', '1/2', '2/1']) +DEV_TNR3_ID, DEV_TNR3_EPS, DEV_TNR3 = compose_router('TN-R3', ['1/1', '1/2', '2/1']) +DEV_TNR4_ID, DEV_TNR4_EPS, DEV_TNR4 = compose_router('TN-R4', ['1/1', '1/2', '2/1']) +tols_ep_uuids = [str(uuid.uuid4()).split('-')[-1] for _ in range(4)] +DEV_TOLS_ID, DEV_TOLS_EPS, DEV_TOLS = compose_ols('TN-OLS', tols_ep_uuids) + + +# ----- Links ---------------------------------------------------------------------------------------------------------- +# InterDomain DC-CSGW +LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW1 = compose_link(DEV_DC1GW_EPS[0], DEV_CS1GW1_EPS[0]) +LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1GW2_EPS[0]) +LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0]) +LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0]) + +# InterDomain CSGW-TN +LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0]) +LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0]) +LINK_CS1GW1_TNR2_ID, LINK_CS1GW1_TNR2 = compose_link(DEV_CS1GW1_EPS[2], DEV_TNR2_EPS[1]) +LINK_CS1GW2_TNR1_ID, LINK_CS1GW2_TNR1 = compose_link(DEV_CS1GW2_EPS[2], DEV_TNR1_EPS[1]) +LINK_CS2GW1_TNR3_ID, LINK_CS2GW1_TNR3 = compose_link(DEV_CS2GW1_EPS[1], DEV_TNR3_EPS[0]) +LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4_EPS[0]) +LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1]) +LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1]) + +# IntraDomain TN +LINK_TNR1_TOLS_ID, LINK_TNR1_TOLS = compose_link(DEV_TNR1_EPS[2], DEV_TOLS_EPS[0]) +LINK_TNR2_TOLS_ID, LINK_TNR2_TOLS = compose_link(DEV_TNR2_EPS[2], DEV_TOLS_EPS[1]) +LINK_TNR3_TOLS_ID, LINK_TNR3_TOLS = compose_link(DEV_TNR3_EPS[2], DEV_TOLS_EPS[2]) +LINK_TNR4_TOLS_ID, LINK_TNR4_TOLS = compose_link(DEV_TNR4_EPS[2], DEV_TOLS_EPS[3]) + + +# ----- Service -------------------------------------------------------------------------------------------------------- +SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[ + json_constraint_custom('bandwidth[gbps]', 10.0), + json_constraint_custom('latency[ms]', 12.0), +]) + +# ----- Containers ----------------------------------------------------------------------------------------------------- +CONTEXTS = [ CONTEXT ] +TOPOLOGIES = [ TOPO_ADMIN, TOPO_DC1, TOPO_DC2, TOPO_CS1, TOPO_CS2, TOPO_TN ] +DEVICES = [ DEV_DC1GW, DEV_DC2GW, + DEV_CS1GW1, DEV_CS1GW2, DEV_CS2GW1, DEV_CS2GW2, + DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4, + DEV_TOLS, + ] +LINKS = [ LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2, + LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1, + LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3, + LINK_TNR1_TOLS, LINK_TNR2_TOLS, LINK_TNR3_TOLS, LINK_TNR4_TOLS, + ] +SERVICES = [ SERVICE_DC1GW_DC2GW ] + +OBJECTS_PER_TOPOLOGY = [ + (TOPO_ADMIN_ID, + [ DEV_DC1GW_ID, DEV_DC2GW_ID, + DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID, + DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, + DEV_TOLS_ID, + ], + [ LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID, + LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID, + LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID, + LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID, + ], + ), + (TOPO_DC1_ID, + [DEV_DC1GW_ID], + []), + (TOPO_DC2_ID, + [DEV_DC2GW_ID], + []), + (TOPO_CS1_ID, + [DEV_CS1GW1_ID, DEV_CS1GW2_ID], + []), + (TOPO_CS2_ID, + [DEV_CS2GW1_ID, DEV_CS2GW2_ID], + []), + (TOPO_TN_ID, + [ DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID, + DEV_TOLS_ID, + ], + [ LINK_TNR1_TOLS_ID, LINK_TNR2_TOLS_ID, LINK_TNR3_TOLS_ID, LINK_TNR4_TOLS_ID, + ]), +] diff --git a/src/pathcomp/frontend/tests/test_unitary.py b/src/pathcomp/frontend/tests/test_unitary.py index 2368a6c0ade2bd0125a0a8df66560496fe782a1d..c09d4c7100629449e250dc87019f69f8ce6c3429 100644 --- a/src/pathcomp/frontend/tests/test_unitary.py +++ b/src/pathcomp/frontend/tests/test_unitary.py @@ -16,7 +16,12 @@ import copy, logging, os from common.proto.context_pb2 import Context, ContextId, DeviceId, Link, LinkId, Topology, Device, TopologyId from common.proto.pathcomp_pb2 import PathCompRequest from common.tools.grpc.Tools import grpc_message_to_json -from common.tools.object_factory.Constraint import json_constraint +from common.tools.object_factory.Constraint import ( + json_constraint_custom, json_constraint_endpoint_location_region, json_constraint_endpoint_priority, + json_constraint_sla_availability) +from common.tools.object_factory.Device import json_device_id +from common.tools.object_factory.EndPoint import json_endpoint_id +from common.tools.object_factory.Service import json_service_l3nm_planned from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from pathcomp.frontend.client.PathCompClient import PathCompClient @@ -24,6 +29,7 @@ from pathcomp.frontend.client.PathCompClient import PathCompClient # Scenarios: #from .Objects_A_B_C import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES from .Objects_DC_CSGW_TN import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES +#from .Objects_DC_CSGW_TN_OLS import CONTEXTS, DEVICES, LINKS, OBJECTS_PER_TOPOLOGY, SERVICES, TOPOLOGIES # configure backend environment variables before overwriting them with fixtures to use real backend pathcomp DEFAULT_PATHCOMP_BACKEND_SCHEME = 'http' @@ -85,8 +91,8 @@ def test_request_service_shortestpath( request_services = copy.deepcopy(SERVICES) #request_services[0]['service_constraints'] = [ - # json_constraint('bandwidth[gbps]', 1000.0), - # json_constraint('latency[ms]', 1200.0), + # json_constraint_custom('bandwidth[gbps]', 1000.0), + # json_constraint_custom('latency[ms]', 1200.0), #] pathcomp_request = PathCompRequest(services=request_services) pathcomp_request.shortest_path.Clear() # hack to select the shortest path algorithm that has no attributes @@ -188,7 +194,33 @@ def test_request_service_kshortestpath( def test_request_service_kdisjointpath( pathcomp_client : PathCompClient): # pylint: disable=redefined-outer-name - request_services = SERVICES + service_uuid = 'DC1-DC2' + raw_endpoints = [ + ('CS1-GW1', '10/1', 'DC1', 10), + ('CS1-GW2', '10/1', 'DC1', 20), + ('CS2-GW1', '10/1', 'DC2', 10), + ('CS2-GW2', '10/1', 'DC2', 20), + ] + + endpoint_ids, constraints = [], [ + json_constraint_custom('bandwidth[gbps]', 10.0), + json_constraint_custom('latency[ms]', 12.0), + json_constraint_sla_availability(2, True), + json_constraint_custom('diversity', {'end-to-end-diverse': 'all-other-accesses'}), + ] + + for device_uuid, endpoint_uuid, region, priority in raw_endpoints: + device_id = json_device_id(device_uuid) + endpoint_id = json_endpoint_id(device_id, endpoint_uuid) + endpoint_ids.append(endpoint_id) + constraints.extend([ + json_constraint_endpoint_location_region(endpoint_id, region), + json_constraint_endpoint_priority(endpoint_id, priority), + ]) + + service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints) + request_services = [service] + pathcomp_request = PathCompRequest(services=request_services) pathcomp_request.k_disjoint_path.num_disjoint = 2 #pylint: disable=no-member diff --git a/src/service/tests/ServiceHandler_L3NM_EMU.py b/src/service/tests/ServiceHandler_L3NM_EMU.py index 0ac5fbf24cf1937104646374f60ab9487ee1c84d..45df80e4265018e802be587285fce318fc6b0736 100644 --- a/src/service/tests/ServiceHandler_L3NM_EMU.py +++ b/src/service/tests/ServiceHandler_L3NM_EMU.py @@ -14,7 +14,7 @@ from typing import Dict, List, Tuple from common.tools.object_factory.ConfigRule import json_config_rule_set -from common.tools.object_factory.Constraint import json_constraint +from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Device import ( json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled, json_device_id) from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id @@ -101,8 +101,8 @@ SERVICE_R1_R3_UUID = 'SVC:{:s}/{:s}-{:s}/{:s}'.format( DEVICE_R3_UUID, ENDPOINT_ID_R3_EP100['endpoint_uuid']['uuid']) SERVICE_R1_R3_ENDPOINT_IDS = [ENDPOINT_ID_R1_EP100, ENDPOINT_ID_R3_EP100] SERVICE_R1_R3_CONSTRAINTS = [ - json_constraint('latency_ms', 15.2), - json_constraint('jitter_us', 1.2), + json_constraint_custom('latency_ms', 15.2), + json_constraint_custom('jitter_us', 1.2), ] SERVICE_R1_R3_CONFIG_RULES = [ json_config_rule_set( diff --git a/src/service/tests/ServiceHandler_L3NM_OC.py b/src/service/tests/ServiceHandler_L3NM_OC.py index 0797a4af5505e78e2af49cefc29970f9c8ff11e7..717536f6d1ee60564752f3107cd366796e3a36e2 100644 --- a/src/service/tests/ServiceHandler_L3NM_OC.py +++ b/src/service/tests/ServiceHandler_L3NM_OC.py @@ -15,7 +15,7 @@ import uuid from typing import Dict, List, Tuple from common.tools.object_factory.ConfigRule import json_config_rule_set -from common.tools.object_factory.Constraint import json_constraint +from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.Device import ( json_device_connect_rules, json_device_emulated_packet_router_disabled, json_device_emulated_tapi_disabled, json_device_id) @@ -115,8 +115,8 @@ SERVICE_R1_R2_UUID = 'SVC:{:s}/{:s}-{:s}/{:s}'.format( DEVICE_R2_UUID, ENDPOINT_ID_R2_EP100['endpoint_uuid']['uuid']) SERVICE_R1_R2_ENDPOINT_IDS = [ENDPOINT_ID_R1_EP100, ENDPOINT_ID_R2_EP100] SERVICE_R1_R2_CONSTRAINTS = [ - json_constraint('latency_ms', 15.2), - json_constraint('jitter_us', 1.2), + json_constraint_custom('latency_ms', 15.2), + json_constraint_custom('jitter_us', 1.2), ] SERVICE_R1_R2_CONFIG_RULES = [ json_config_rule_set(