Loading src/common/tools/descriptor/Loader.py +44 −5 Original line number Diff line number Diff line Loading @@ -222,13 +222,13 @@ class DescriptorLoader: self.__topologies_add = get_descriptors_add_topologies(self.__topologies) if self.__dummy_mode: self._dummy_mode() self._load_dummy_mode() else: self._normal_mode() self._load_normal_mode() return self.__results def _dummy_mode(self) -> None: def _load_dummy_mode(self) -> None: # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. self.__ctx_cli.connect() self._process_descr('context', 'add', self.__ctx_cli.SetContext, Context, self.__contexts_add ) Loading @@ -242,7 +242,7 @@ class DescriptorLoader: self._process_descr('topology', 'update', self.__ctx_cli.SetTopology, Topology, self.__topologies ) #self.__ctx_cli.close() def _normal_mode(self) -> None: def _load_normal_mode(self) -> None: # Normal mode: follows the automated workflows in the different components assert len(self.__connections) == 0, 'in normal mode, connections should not be set' Loading Loading @@ -321,7 +321,35 @@ class DescriptorLoader: response = self.__ctx_cli.ListSlices(ContextId(**json_context_id(context_uuid))) assert len(response.slices) == num_slices def unload(self) -> None: def _unload_dummy_mode(self) -> None: # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. self.__ctx_cli.connect() for _, slice_list in self.slices.items(): for slice_ in slice_list: self.__ctx_cli.RemoveSlice(SliceId(**slice_['slice_id'])) for _, service_list in self.services.items(): for service in service_list: self.__ctx_cli.RemoveService(ServiceId(**service['service_id'])) for link in self.links: self.__ctx_cli.RemoveLink(LinkId(**link['link_id'])) for device in self.devices: self.__ctx_cli.RemoveDevice(DeviceId(**device['device_id'])) for _, topology_list in self.topologies.items(): for topology in topology_list: self.__ctx_cli.RemoveTopology(TopologyId(**topology['topology_id'])) for context in self.contexts: self.__ctx_cli.RemoveContext(ContextId(**context['context_id'])) #self.__ctx_cli.close() def _unload_normal_mode(self) -> None: # Normal mode: follows the automated workflows in the different components self.__ctx_cli.connect() self.__dev_cli.connect() self.__svc_cli.connect() Loading @@ -348,6 +376,17 @@ class DescriptorLoader: for context in self.contexts: self.__ctx_cli.RemoveContext(ContextId(**context['context_id'])) #self.__ctx_cli.close() #self.__dev_cli.close() #self.__svc_cli.close() #self.__slc_cli.close() def unload(self) -> None: if self.__dummy_mode: self._unload_dummy_mode() else: self._unload_normal_mode() def compose_notifications(results : TypeResults) -> TypeNotificationList: notifications = [] for entity_name, action_name, num_ok, error_list in results: Loading src/pathcomp/frontend/Dockerfile +8 −2 Original line number Diff line number Diff line Loading @@ -62,8 +62,14 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow COPY src/context/. context/ COPY src/device/. device/ COPY src/context/__init__.py context/__init__.py COPY src/context/client/. context/client/ COPY src/device/__init__.py device/__init__.py COPY src/device/client/. device/client/ COPY src/service/__init__.py service/__init__.py COPY src/service/client/. service/client/ COPY src/slice/__init__.py slice/__init__.py COPY src/slice/client/. slice/client/ COPY src/pathcomp/. pathcomp/ # Start the service Loading src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py +21 −64 Original line number Diff line number Diff line Loading @@ -14,12 +14,10 @@ import operator from typing import Dict, List, Optional, Set, Tuple from common.proto.context_pb2 import Connection, Link, Service from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompReply, PathCompRequest from common.proto.context_pb2 import Link from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompRequest from common.tools.grpc.Tools import grpc_message_to_json_string from pathcomp.frontend.service.algorithms.tools.ComputeSubServices import convert_explicit_path_hops_to_connections from pathcomp.frontend.service.algorithms.tools.EroPathToHops import eropath_to_hops from ._Algorithm import _Algorithm from ._Algorithm import _Algorithm, SRC_END from .KShortestPathAlgorithm import KShortestPathAlgorithm Service_Id = Tuple[str, str] # (context_uuid, service_uuid) Loading Loading @@ -100,7 +98,7 @@ class KDisjointPathAlgorithm(_Algorithm): def get_link_from_endpoint(self, endpoint : Dict) -> Tuple[Dict, Link]: device_uuid = endpoint['device_id'] endpoint_uuid = endpoint['endpoint_uuid'] item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid)) item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid, SRC_END)) if item is None: MSG = 'Link for Endpoint({:s}, {:s}) not found' self.logger.warning(MSG.format(device_uuid, endpoint_uuid)) Loading Loading @@ -141,7 +139,7 @@ class KDisjointPathAlgorithm(_Algorithm): Path = List[Dict] Path_NoPath = Optional[Path] # None = no path, list = path self.json_reply : Dict[Tuple[str, str], List[Path_NoPath]] = dict() service_to_paths : Dict[Tuple[str, str], List[Path_NoPath]] = dict() for num_path in range(self.num_disjoint): algorithm.service_list = list() Loading Loading @@ -189,66 +187,25 @@ class KDisjointPathAlgorithm(_Algorithm): for response in response_list: service_id = response['serviceId'] service_key = (service_id['contextId'], service_id['service_uuid']) json_reply_service = self.json_reply.setdefault(service_key, list()) json_reply_service = service_to_paths.setdefault(service_key, list()) no_path_issue = response.get('noPath', {}).get('issue') if no_path_issue is not None: json_reply_service.append(None) continue if no_path_issue is not None: continue path_endpoints = response['path'][0]['devices'] path_endpoints = response['path'][0] json_reply_service.append(path_endpoints) algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints) algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints['devices']) self.json_reply = dict() response_list = self.json_reply.setdefault('response-list', []) for service_key,paths in service_to_paths.items(): response = {'serviceId': { 'contextId': service_key[0], 'service_uuid': service_key[1], }} response['path'] = paths if len(paths) < self.num_disjoint: response['noPath'] = {'issue': 1} response_list.append(response) self.logger.debug('self.json_reply = {:s}'.format(str(self.json_reply))) def get_reply(self) -> PathCompReply: reply = PathCompReply() grpc_services : Dict[Tuple[str, str], Service] = {} grpc_connections : Dict[Tuple[int, str], Connection] = {} for service_key,paths in self.json_reply.items(): context_uuid, service_uuid = service_key grpc_services[service_key] = self.add_service_to_reply(reply, context_uuid, service_uuid) for num_path,service_path_ero in enumerate(paths): self.logger.warning('num_path={:d}'.format(num_path)) self.logger.warning('service_path_ero={:s}'.format(str(service_path_ero))) if service_path_ero is None: continue path_hops = eropath_to_hops(service_path_ero, self.endpoint_to_link_dict) self.logger.warning('path_hops={:s}'.format(str(path_hops))) connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid) self.logger.warning('connections={:s}'.format(str(connections))) for connection in connections: connection_uuid,device_layer,path_hops,_ = connection service_key = (context_uuid, connection_uuid) grpc_service = grpc_services.get(service_key) if grpc_service is not None: continue grpc_service = self.add_service_to_reply( reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops) grpc_services[service_key] = grpc_service for connection in connections: connection_uuid,device_layer,path_hops,dependencies = connection service_key = (context_uuid, connection_uuid) grpc_service = grpc_services.get(service_key) if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key))) connection_uuid = '{:s}:{:d}'.format(connection_uuid, num_path) grpc_connection = grpc_connections.get(connection_uuid) if grpc_connection is not None: continue grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops) grpc_connections[connection_uuid] = grpc_connection for sub_service_uuid in dependencies: sub_service_key = (context_uuid, sub_service_uuid) grpc_sub_service = grpc_services.get(sub_service_key) if grpc_sub_service is None: raise Exception('Service({:s}) not found'.format(str(sub_service_key))) grpc_sub_service_id = grpc_connection.sub_service_ids.add() grpc_sub_service_id.CopyFrom(grpc_sub_service.service_id) return reply src/pathcomp/frontend/tests/Objects_A_B_C.py +46 −24 Original line number Diff line number Diff line Loading @@ -80,21 +80,36 @@ DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', ' LINK_A2_C3_ID, LINK_A2_C3 = compose_link(DEVICE_A2_ENDPOINTS[2], DEVICE_C3_ENDPOINTS[2]) LINK_C1_B2_ID, LINK_C1_B2 = compose_link(DEVICE_C1_ENDPOINTS[2], DEVICE_B2_ENDPOINTS[2]) LINK_C3_A2_ID, LINK_C3_A2 = compose_link(DEVICE_C3_ENDPOINTS[2], DEVICE_A2_ENDPOINTS[2]) LINK_B2_C1_ID, LINK_B2_C1 = compose_link(DEVICE_B2_ENDPOINTS[2], DEVICE_C1_ENDPOINTS[2]) # ----- IntraDomain A Links -------------------------------------------------------------------------------------------- LINK_A1_A2_ID, LINK_A1_A2 = compose_link(DEVICE_A1_ENDPOINTS[0], DEVICE_A2_ENDPOINTS[0]) LINK_A1_A3_ID, LINK_A1_A3 = compose_link(DEVICE_A1_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[0]) LINK_A2_A3_ID, LINK_A2_A3 = compose_link(DEVICE_A2_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[1]) LINK_A2_A1_ID, LINK_A2_A1 = compose_link(DEVICE_A2_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[0]) LINK_A3_A1_ID, LINK_A3_A1 = compose_link(DEVICE_A3_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[1]) LINK_A3_A2_ID, LINK_A3_A2 = compose_link(DEVICE_A3_ENDPOINTS[1], DEVICE_A2_ENDPOINTS[1]) # ----- IntraDomain B Links -------------------------------------------------------------------------------------------- LINK_B1_B2_ID, LINK_B1_B2 = compose_link(DEVICE_B1_ENDPOINTS[0], DEVICE_B2_ENDPOINTS[0]) LINK_B1_B3_ID, LINK_B1_B3 = compose_link(DEVICE_B1_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[0]) LINK_B2_B3_ID, LINK_B2_B3 = compose_link(DEVICE_B2_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[1]) LINK_B2_B1_ID, LINK_B2_B1 = compose_link(DEVICE_B2_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[0]) LINK_B3_B1_ID, LINK_B3_B1 = compose_link(DEVICE_B3_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[1]) LINK_B3_B2_ID, LINK_B3_B2 = compose_link(DEVICE_B3_ENDPOINTS[1], DEVICE_B2_ENDPOINTS[1]) # ----- IntraDomain C Links -------------------------------------------------------------------------------------------- LINK_C1_C2_ID, LINK_C1_C2 = compose_link(DEVICE_C1_ENDPOINTS[0], DEVICE_C2_ENDPOINTS[0]) LINK_C1_C3_ID, LINK_C1_C3 = compose_link(DEVICE_C1_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[0]) LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[1]) LINK_C2_C1_ID, LINK_C2_C1 = compose_link(DEVICE_C2_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[0]) LINK_C3_C1_ID, LINK_C3_C1 = compose_link(DEVICE_C3_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[1]) LINK_C3_C2_ID, LINK_C3_C2 = compose_link(DEVICE_C3_ENDPOINTS[1], DEVICE_C2_ENDPOINTS[1]) # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[ json_constraint_sla_capacity(10.0), Loading @@ -108,31 +123,38 @@ DEVICES = [ DEVICE_A1, DEVICE_A2, DEVICE_A3, DEVICE_B1, DEVICE_B2, DEVICE_B3, DEVICE_C1, DEVICE_C2, DEVICE_C3, ] LINKS = [ LINK_A2_C3, LINK_C1_B2, LINK_C3_A2, LINK_B2_C1, LINK_A1_A2, LINK_A1_A3, LINK_A2_A3, LINK_A2_A1, LINK_A3_A1, LINK_A3_A2, LINK_B1_B2, LINK_B1_B3, LINK_B2_B3, LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, ] LINK_B2_B1, LINK_B3_B1, LINK_B3_B2, LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, LINK_C2_C1, LINK_C3_C1, LINK_C3_C2, ] SERVICES = [ SERVICE_A1_B1] OBJECTS_PER_TOPOLOGY = [ (TOPOLOGY_ADMIN_ID, [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], [ LINK_A2_C3_ID, LINK_C1_B2_ID, LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], ), (TOPOLOGY_A_ID, [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, ], [ LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, ], ), (TOPOLOGY_B_ID, [ DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, ], [ LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, ], ), (TOPOLOGY_C_ID, [ DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], [ LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], ), ] #OBJECTS_PER_TOPOLOGY = [ # (TOPOLOGY_ADMIN_ID, # [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, # DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, # DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], # [ LINK_A2_C3_ID, LINK_C1_B2_ID, # LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, # LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, # LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], # ), # (TOPOLOGY_A_ID, # [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, ], # [ LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, ], # ), # (TOPOLOGY_B_ID, # [ DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, ], # [ LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, ], # ), # (TOPOLOGY_C_ID, # [ DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], # [ LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], # ), #] src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py +56 −32 Original line number Diff line number Diff line Loading @@ -118,6 +118,11 @@ LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1 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]) LINK_CS1GW1_DC1GW_ID, LINK_CS1GW1_DC1GW = compose_link(DEV_CS1GW1_EPS[0], DEV_DC1GW_EPS[0]) LINK_CS1GW2_DC1GW_ID, LINK_CS1GW2_DC1GW = compose_link(DEV_CS1GW2_EPS[0], DEV_DC1GW_EPS[1]) LINK_CS2GW1_DC2GW_ID, LINK_CS2GW1_DC2GW = compose_link(DEV_CS2GW1_EPS[0], DEV_DC2GW_EPS[0]) LINK_CS2GW2_DC2GW_ID, LINK_CS2GW2_DC2GW = compose_link(DEV_CS2GW2_EPS[0], DEV_DC2GW_EPS[1]) # 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]) Loading @@ -128,6 +133,15 @@ LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4 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]) LINK_TNR1_CS1GW1_ID, LINK_TNR1_CS1GW1 = compose_link(DEV_TNR1_EPS[0], DEV_CS1GW1_EPS[1]) LINK_TNR2_CS1GW2_ID, LINK_TNR2_CS1GW2 = compose_link(DEV_TNR2_EPS[0], DEV_CS1GW2_EPS[1]) LINK_TNR2_CS1GW1_ID, LINK_TNR2_CS1GW1 = compose_link(DEV_TNR2_EPS[1], DEV_CS1GW1_EPS[2]) LINK_TNR1_CS1GW2_ID, LINK_TNR1_CS1GW2 = compose_link(DEV_TNR1_EPS[1], DEV_CS1GW2_EPS[2]) LINK_TNR3_CS2GW1_ID, LINK_TNR3_CS2GW1 = compose_link(DEV_TNR3_EPS[0], DEV_CS2GW1_EPS[1]) LINK_TNR4_CS2GW2_ID, LINK_TNR4_CS2GW2 = compose_link(DEV_TNR4_EPS[0], DEV_CS2GW2_EPS[1]) LINK_TNR4_CS2GW1_ID, LINK_TNR4_CS2GW1 = compose_link(DEV_TNR4_EPS[1], DEV_CS2GW1_EPS[2]) LINK_TNR3_CS2GW2_ID, LINK_TNR3_CS2GW2 = compose_link(DEV_TNR3_EPS[1], DEV_CS2GW2_EPS[2]) # IntraDomain TN LINK_TNR1_TNR2_ID, LINK_TNR1_TNR2 = compose_link(DEV_TNR1_EPS[2], DEV_TNR2_EPS[3]) LINK_TNR2_TNR3_ID, LINK_TNR2_TNR3 = compose_link(DEV_TNR2_EPS[2], DEV_TNR3_EPS[3]) Loading @@ -136,6 +150,13 @@ LINK_TNR4_TNR1_ID, LINK_TNR4_TNR1 = compose_link(DEV_TNR4_EPS[2], DEV_TNR1_EPS[3 LINK_TNR1_TNR3_ID, LINK_TNR1_TNR3 = compose_link(DEV_TNR1_EPS[4], DEV_TNR3_EPS[4]) LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4]) LINK_TNR2_TNR1_ID, LINK_TNR2_TNR1 = compose_link(DEV_TNR2_EPS[3], DEV_TNR1_EPS[2]) LINK_TNR3_TNR2_ID, LINK_TNR3_TNR2 = compose_link(DEV_TNR3_EPS[3], DEV_TNR2_EPS[2]) LINK_TNR4_TNR3_ID, LINK_TNR4_TNR3 = compose_link(DEV_TNR4_EPS[3], DEV_TNR3_EPS[2]) LINK_TNR1_TNR4_ID, LINK_TNR1_TNR4 = compose_link(DEV_TNR1_EPS[3], DEV_TNR4_EPS[2]) LINK_TNR3_TNR1_ID, LINK_TNR3_TNR1 = compose_link(DEV_TNR3_EPS[4], DEV_TNR1_EPS[4]) LINK_TNR4_TNR2_ID, LINK_TNR4_TNR2 = compose_link(DEV_TNR4_EPS[4], DEV_TNR2_EPS[4]) # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[ Loading @@ -151,41 +172,44 @@ DEVICES = [ DEV_DC1GW, DEV_DC2GW, DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4, ] LINKS = [ LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2, LINK_CS1GW1_DC1GW, LINK_CS1GW2_DC1GW, LINK_CS2GW1_DC2GW, LINK_CS2GW2_DC2GW, 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_TNR2_TNR1, LINK_TNR3_TNR2, LINK_TNR4_TNR3, LINK_TNR1_TNR4, LINK_TNR3_TNR1, LINK_TNR4_TNR2, ] 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, ], [ 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, ], ), (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, ], [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, LINK_TNR2_TNR4_ID, ]), ] #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, # ], # [ 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, # ], # ), # (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, # ], # [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, # LINK_TNR2_TNR4_ID, # ]), #] Loading
src/common/tools/descriptor/Loader.py +44 −5 Original line number Diff line number Diff line Loading @@ -222,13 +222,13 @@ class DescriptorLoader: self.__topologies_add = get_descriptors_add_topologies(self.__topologies) if self.__dummy_mode: self._dummy_mode() self._load_dummy_mode() else: self._normal_mode() self._load_normal_mode() return self.__results def _dummy_mode(self) -> None: def _load_dummy_mode(self) -> None: # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. self.__ctx_cli.connect() self._process_descr('context', 'add', self.__ctx_cli.SetContext, Context, self.__contexts_add ) Loading @@ -242,7 +242,7 @@ class DescriptorLoader: self._process_descr('topology', 'update', self.__ctx_cli.SetTopology, Topology, self.__topologies ) #self.__ctx_cli.close() def _normal_mode(self) -> None: def _load_normal_mode(self) -> None: # Normal mode: follows the automated workflows in the different components assert len(self.__connections) == 0, 'in normal mode, connections should not be set' Loading Loading @@ -321,7 +321,35 @@ class DescriptorLoader: response = self.__ctx_cli.ListSlices(ContextId(**json_context_id(context_uuid))) assert len(response.slices) == num_slices def unload(self) -> None: def _unload_dummy_mode(self) -> None: # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. self.__ctx_cli.connect() for _, slice_list in self.slices.items(): for slice_ in slice_list: self.__ctx_cli.RemoveSlice(SliceId(**slice_['slice_id'])) for _, service_list in self.services.items(): for service in service_list: self.__ctx_cli.RemoveService(ServiceId(**service['service_id'])) for link in self.links: self.__ctx_cli.RemoveLink(LinkId(**link['link_id'])) for device in self.devices: self.__ctx_cli.RemoveDevice(DeviceId(**device['device_id'])) for _, topology_list in self.topologies.items(): for topology in topology_list: self.__ctx_cli.RemoveTopology(TopologyId(**topology['topology_id'])) for context in self.contexts: self.__ctx_cli.RemoveContext(ContextId(**context['context_id'])) #self.__ctx_cli.close() def _unload_normal_mode(self) -> None: # Normal mode: follows the automated workflows in the different components self.__ctx_cli.connect() self.__dev_cli.connect() self.__svc_cli.connect() Loading @@ -348,6 +376,17 @@ class DescriptorLoader: for context in self.contexts: self.__ctx_cli.RemoveContext(ContextId(**context['context_id'])) #self.__ctx_cli.close() #self.__dev_cli.close() #self.__svc_cli.close() #self.__slc_cli.close() def unload(self) -> None: if self.__dummy_mode: self._unload_dummy_mode() else: self._unload_normal_mode() def compose_notifications(results : TypeResults) -> TypeNotificationList: notifications = [] for entity_name, action_name, num_ok, error_list in results: Loading
src/pathcomp/frontend/Dockerfile +8 −2 Original line number Diff line number Diff line Loading @@ -62,8 +62,14 @@ RUN python3 -m pip install -r requirements.txt # Add component files into working directory WORKDIR /var/teraflow COPY src/context/. context/ COPY src/device/. device/ COPY src/context/__init__.py context/__init__.py COPY src/context/client/. context/client/ COPY src/device/__init__.py device/__init__.py COPY src/device/client/. device/client/ COPY src/service/__init__.py service/__init__.py COPY src/service/client/. service/client/ COPY src/slice/__init__.py slice/__init__.py COPY src/slice/client/. slice/client/ COPY src/pathcomp/. pathcomp/ # Start the service Loading
src/pathcomp/frontend/service/algorithms/KDisjointPathAlgorithm.py +21 −64 Original line number Diff line number Diff line Loading @@ -14,12 +14,10 @@ import operator from typing import Dict, List, Optional, Set, Tuple from common.proto.context_pb2 import Connection, Link, Service from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompReply, PathCompRequest from common.proto.context_pb2 import Link from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompRequest from common.tools.grpc.Tools import grpc_message_to_json_string from pathcomp.frontend.service.algorithms.tools.ComputeSubServices import convert_explicit_path_hops_to_connections from pathcomp.frontend.service.algorithms.tools.EroPathToHops import eropath_to_hops from ._Algorithm import _Algorithm from ._Algorithm import _Algorithm, SRC_END from .KShortestPathAlgorithm import KShortestPathAlgorithm Service_Id = Tuple[str, str] # (context_uuid, service_uuid) Loading Loading @@ -100,7 +98,7 @@ class KDisjointPathAlgorithm(_Algorithm): def get_link_from_endpoint(self, endpoint : Dict) -> Tuple[Dict, Link]: device_uuid = endpoint['device_id'] endpoint_uuid = endpoint['endpoint_uuid'] item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid)) item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid, SRC_END)) if item is None: MSG = 'Link for Endpoint({:s}, {:s}) not found' self.logger.warning(MSG.format(device_uuid, endpoint_uuid)) Loading Loading @@ -141,7 +139,7 @@ class KDisjointPathAlgorithm(_Algorithm): Path = List[Dict] Path_NoPath = Optional[Path] # None = no path, list = path self.json_reply : Dict[Tuple[str, str], List[Path_NoPath]] = dict() service_to_paths : Dict[Tuple[str, str], List[Path_NoPath]] = dict() for num_path in range(self.num_disjoint): algorithm.service_list = list() Loading Loading @@ -189,66 +187,25 @@ class KDisjointPathAlgorithm(_Algorithm): for response in response_list: service_id = response['serviceId'] service_key = (service_id['contextId'], service_id['service_uuid']) json_reply_service = self.json_reply.setdefault(service_key, list()) json_reply_service = service_to_paths.setdefault(service_key, list()) no_path_issue = response.get('noPath', {}).get('issue') if no_path_issue is not None: json_reply_service.append(None) continue if no_path_issue is not None: continue path_endpoints = response['path'][0]['devices'] path_endpoints = response['path'][0] json_reply_service.append(path_endpoints) algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints) algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints['devices']) self.json_reply = dict() response_list = self.json_reply.setdefault('response-list', []) for service_key,paths in service_to_paths.items(): response = {'serviceId': { 'contextId': service_key[0], 'service_uuid': service_key[1], }} response['path'] = paths if len(paths) < self.num_disjoint: response['noPath'] = {'issue': 1} response_list.append(response) self.logger.debug('self.json_reply = {:s}'.format(str(self.json_reply))) def get_reply(self) -> PathCompReply: reply = PathCompReply() grpc_services : Dict[Tuple[str, str], Service] = {} grpc_connections : Dict[Tuple[int, str], Connection] = {} for service_key,paths in self.json_reply.items(): context_uuid, service_uuid = service_key grpc_services[service_key] = self.add_service_to_reply(reply, context_uuid, service_uuid) for num_path,service_path_ero in enumerate(paths): self.logger.warning('num_path={:d}'.format(num_path)) self.logger.warning('service_path_ero={:s}'.format(str(service_path_ero))) if service_path_ero is None: continue path_hops = eropath_to_hops(service_path_ero, self.endpoint_to_link_dict) self.logger.warning('path_hops={:s}'.format(str(path_hops))) connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid) self.logger.warning('connections={:s}'.format(str(connections))) for connection in connections: connection_uuid,device_layer,path_hops,_ = connection service_key = (context_uuid, connection_uuid) grpc_service = grpc_services.get(service_key) if grpc_service is not None: continue grpc_service = self.add_service_to_reply( reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops) grpc_services[service_key] = grpc_service for connection in connections: connection_uuid,device_layer,path_hops,dependencies = connection service_key = (context_uuid, connection_uuid) grpc_service = grpc_services.get(service_key) if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key))) connection_uuid = '{:s}:{:d}'.format(connection_uuid, num_path) grpc_connection = grpc_connections.get(connection_uuid) if grpc_connection is not None: continue grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops) grpc_connections[connection_uuid] = grpc_connection for sub_service_uuid in dependencies: sub_service_key = (context_uuid, sub_service_uuid) grpc_sub_service = grpc_services.get(sub_service_key) if grpc_sub_service is None: raise Exception('Service({:s}) not found'.format(str(sub_service_key))) grpc_sub_service_id = grpc_connection.sub_service_ids.add() grpc_sub_service_id.CopyFrom(grpc_sub_service.service_id) return reply
src/pathcomp/frontend/tests/Objects_A_B_C.py +46 −24 Original line number Diff line number Diff line Loading @@ -80,21 +80,36 @@ DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', ' LINK_A2_C3_ID, LINK_A2_C3 = compose_link(DEVICE_A2_ENDPOINTS[2], DEVICE_C3_ENDPOINTS[2]) LINK_C1_B2_ID, LINK_C1_B2 = compose_link(DEVICE_C1_ENDPOINTS[2], DEVICE_B2_ENDPOINTS[2]) LINK_C3_A2_ID, LINK_C3_A2 = compose_link(DEVICE_C3_ENDPOINTS[2], DEVICE_A2_ENDPOINTS[2]) LINK_B2_C1_ID, LINK_B2_C1 = compose_link(DEVICE_B2_ENDPOINTS[2], DEVICE_C1_ENDPOINTS[2]) # ----- IntraDomain A Links -------------------------------------------------------------------------------------------- LINK_A1_A2_ID, LINK_A1_A2 = compose_link(DEVICE_A1_ENDPOINTS[0], DEVICE_A2_ENDPOINTS[0]) LINK_A1_A3_ID, LINK_A1_A3 = compose_link(DEVICE_A1_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[0]) LINK_A2_A3_ID, LINK_A2_A3 = compose_link(DEVICE_A2_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[1]) LINK_A2_A1_ID, LINK_A2_A1 = compose_link(DEVICE_A2_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[0]) LINK_A3_A1_ID, LINK_A3_A1 = compose_link(DEVICE_A3_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[1]) LINK_A3_A2_ID, LINK_A3_A2 = compose_link(DEVICE_A3_ENDPOINTS[1], DEVICE_A2_ENDPOINTS[1]) # ----- IntraDomain B Links -------------------------------------------------------------------------------------------- LINK_B1_B2_ID, LINK_B1_B2 = compose_link(DEVICE_B1_ENDPOINTS[0], DEVICE_B2_ENDPOINTS[0]) LINK_B1_B3_ID, LINK_B1_B3 = compose_link(DEVICE_B1_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[0]) LINK_B2_B3_ID, LINK_B2_B3 = compose_link(DEVICE_B2_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[1]) LINK_B2_B1_ID, LINK_B2_B1 = compose_link(DEVICE_B2_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[0]) LINK_B3_B1_ID, LINK_B3_B1 = compose_link(DEVICE_B3_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[1]) LINK_B3_B2_ID, LINK_B3_B2 = compose_link(DEVICE_B3_ENDPOINTS[1], DEVICE_B2_ENDPOINTS[1]) # ----- IntraDomain C Links -------------------------------------------------------------------------------------------- LINK_C1_C2_ID, LINK_C1_C2 = compose_link(DEVICE_C1_ENDPOINTS[0], DEVICE_C2_ENDPOINTS[0]) LINK_C1_C3_ID, LINK_C1_C3 = compose_link(DEVICE_C1_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[0]) LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[1]) LINK_C2_C1_ID, LINK_C2_C1 = compose_link(DEVICE_C2_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[0]) LINK_C3_C1_ID, LINK_C3_C1 = compose_link(DEVICE_C3_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[1]) LINK_C3_C2_ID, LINK_C3_C2 = compose_link(DEVICE_C3_ENDPOINTS[1], DEVICE_C2_ENDPOINTS[1]) # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[ json_constraint_sla_capacity(10.0), Loading @@ -108,31 +123,38 @@ DEVICES = [ DEVICE_A1, DEVICE_A2, DEVICE_A3, DEVICE_B1, DEVICE_B2, DEVICE_B3, DEVICE_C1, DEVICE_C2, DEVICE_C3, ] LINKS = [ LINK_A2_C3, LINK_C1_B2, LINK_C3_A2, LINK_B2_C1, LINK_A1_A2, LINK_A1_A3, LINK_A2_A3, LINK_A2_A1, LINK_A3_A1, LINK_A3_A2, LINK_B1_B2, LINK_B1_B3, LINK_B2_B3, LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, ] LINK_B2_B1, LINK_B3_B1, LINK_B3_B2, LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, LINK_C2_C1, LINK_C3_C1, LINK_C3_C2, ] SERVICES = [ SERVICE_A1_B1] OBJECTS_PER_TOPOLOGY = [ (TOPOLOGY_ADMIN_ID, [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], [ LINK_A2_C3_ID, LINK_C1_B2_ID, LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], ), (TOPOLOGY_A_ID, [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, ], [ LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, ], ), (TOPOLOGY_B_ID, [ DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, ], [ LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, ], ), (TOPOLOGY_C_ID, [ DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], [ LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], ), ] #OBJECTS_PER_TOPOLOGY = [ # (TOPOLOGY_ADMIN_ID, # [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, # DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, # DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], # [ LINK_A2_C3_ID, LINK_C1_B2_ID, # LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, # LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, # LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], # ), # (TOPOLOGY_A_ID, # [ DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID, ], # [ LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID, ], # ), # (TOPOLOGY_B_ID, # [ DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID, ], # [ LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID, ], # ), # (TOPOLOGY_C_ID, # [ DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID, ], # [ LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID, ], # ), #]
src/pathcomp/frontend/tests/Objects_DC_CSGW_TN.py +56 −32 Original line number Diff line number Diff line Loading @@ -118,6 +118,11 @@ LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1 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]) LINK_CS1GW1_DC1GW_ID, LINK_CS1GW1_DC1GW = compose_link(DEV_CS1GW1_EPS[0], DEV_DC1GW_EPS[0]) LINK_CS1GW2_DC1GW_ID, LINK_CS1GW2_DC1GW = compose_link(DEV_CS1GW2_EPS[0], DEV_DC1GW_EPS[1]) LINK_CS2GW1_DC2GW_ID, LINK_CS2GW1_DC2GW = compose_link(DEV_CS2GW1_EPS[0], DEV_DC2GW_EPS[0]) LINK_CS2GW2_DC2GW_ID, LINK_CS2GW2_DC2GW = compose_link(DEV_CS2GW2_EPS[0], DEV_DC2GW_EPS[1]) # 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]) Loading @@ -128,6 +133,15 @@ LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4 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]) LINK_TNR1_CS1GW1_ID, LINK_TNR1_CS1GW1 = compose_link(DEV_TNR1_EPS[0], DEV_CS1GW1_EPS[1]) LINK_TNR2_CS1GW2_ID, LINK_TNR2_CS1GW2 = compose_link(DEV_TNR2_EPS[0], DEV_CS1GW2_EPS[1]) LINK_TNR2_CS1GW1_ID, LINK_TNR2_CS1GW1 = compose_link(DEV_TNR2_EPS[1], DEV_CS1GW1_EPS[2]) LINK_TNR1_CS1GW2_ID, LINK_TNR1_CS1GW2 = compose_link(DEV_TNR1_EPS[1], DEV_CS1GW2_EPS[2]) LINK_TNR3_CS2GW1_ID, LINK_TNR3_CS2GW1 = compose_link(DEV_TNR3_EPS[0], DEV_CS2GW1_EPS[1]) LINK_TNR4_CS2GW2_ID, LINK_TNR4_CS2GW2 = compose_link(DEV_TNR4_EPS[0], DEV_CS2GW2_EPS[1]) LINK_TNR4_CS2GW1_ID, LINK_TNR4_CS2GW1 = compose_link(DEV_TNR4_EPS[1], DEV_CS2GW1_EPS[2]) LINK_TNR3_CS2GW2_ID, LINK_TNR3_CS2GW2 = compose_link(DEV_TNR3_EPS[1], DEV_CS2GW2_EPS[2]) # IntraDomain TN LINK_TNR1_TNR2_ID, LINK_TNR1_TNR2 = compose_link(DEV_TNR1_EPS[2], DEV_TNR2_EPS[3]) LINK_TNR2_TNR3_ID, LINK_TNR2_TNR3 = compose_link(DEV_TNR2_EPS[2], DEV_TNR3_EPS[3]) Loading @@ -136,6 +150,13 @@ LINK_TNR4_TNR1_ID, LINK_TNR4_TNR1 = compose_link(DEV_TNR4_EPS[2], DEV_TNR1_EPS[3 LINK_TNR1_TNR3_ID, LINK_TNR1_TNR3 = compose_link(DEV_TNR1_EPS[4], DEV_TNR3_EPS[4]) LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4]) LINK_TNR2_TNR1_ID, LINK_TNR2_TNR1 = compose_link(DEV_TNR2_EPS[3], DEV_TNR1_EPS[2]) LINK_TNR3_TNR2_ID, LINK_TNR3_TNR2 = compose_link(DEV_TNR3_EPS[3], DEV_TNR2_EPS[2]) LINK_TNR4_TNR3_ID, LINK_TNR4_TNR3 = compose_link(DEV_TNR4_EPS[3], DEV_TNR3_EPS[2]) LINK_TNR1_TNR4_ID, LINK_TNR1_TNR4 = compose_link(DEV_TNR1_EPS[3], DEV_TNR4_EPS[2]) LINK_TNR3_TNR1_ID, LINK_TNR3_TNR1 = compose_link(DEV_TNR3_EPS[4], DEV_TNR1_EPS[4]) LINK_TNR4_TNR2_ID, LINK_TNR4_TNR2 = compose_link(DEV_TNR4_EPS[4], DEV_TNR2_EPS[4]) # ----- Service -------------------------------------------------------------------------------------------------------- SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[ Loading @@ -151,41 +172,44 @@ DEVICES = [ DEV_DC1GW, DEV_DC2GW, DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4, ] LINKS = [ LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2, LINK_CS1GW1_DC1GW, LINK_CS1GW2_DC1GW, LINK_CS2GW1_DC2GW, LINK_CS2GW2_DC2GW, 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_TNR2_TNR1, LINK_TNR3_TNR2, LINK_TNR4_TNR3, LINK_TNR1_TNR4, LINK_TNR3_TNR1, LINK_TNR4_TNR2, ] 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, ], [ 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, ], ), (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, ], [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, LINK_TNR2_TNR4_ID, ]), ] #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, # ], # [ 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, # ], # ), # (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, # ], # [ LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID, # LINK_TNR2_TNR4_ID, # ]), #]