Skip to content
Snippets Groups Projects
Commit c6863d78 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch...

Merge branch 'feat/274-redundant-subservice-creation-after-multi-domain-service-update' into 'develop'

Resolve "Redundant Subservice Creation After Multi-Domain Service Update"

See merge request !331
parents c2a65dc4 681e6276
No related branches found
No related tags found
2 merge requests!359Release TeraFlowSDN 5.0,!331Resolve "Redundant Subservice Creation After Multi-Domain Service Update"
...@@ -45,24 +45,41 @@ ...@@ -45,24 +45,41 @@
# ], [UUID('c2e57966-5d82-4705-a5fe-44cf6487219e')]) # ], [UUID('c2e57966-5d82-4705-a5fe-44cf6487219e')])
# ] # ]
import logging, queue, uuid import logging, queue
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Tuple from typing import Dict, List, Optional, Tuple
from common.DeviceTypes import DeviceTypeEnum from common.DeviceTypes import DeviceTypeEnum
from common.proto.context_pb2 import Device, ServiceTypeEnum from common.proto.context_pb2 import Device, ServiceTypeEnum
from common.tools.context_queries.Slice import get_uuid_from_string
from .ResourceGroups import IGNORED_DEVICE_TYPES, REMOTEDOMAIN_DEVICE_TYPES, get_resource_classification from .ResourceGroups import IGNORED_DEVICE_TYPES, REMOTEDOMAIN_DEVICE_TYPES, get_resource_classification
from .ServiceTypes import get_service_type from .ServiceTypes import get_service_type
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
@dataclass
class ConnectionEntry:
uuid: str = ''
service_type : ServiceTypeEnum = ServiceTypeEnum.SERVICETYPE_UNKNOWN
path_hops : List[Dict] = field(default_factory=list)
dependencies : List['ConnectionEntry'] = field(default_factory=list)
def calculate_subservice_uuid(self, main_service_uuid: str) -> None:
if self.uuid:
return
composed_string = main_service_uuid + '-'.join(
f'{path_hop["device"]}/{path_hop["ingress_ep"]}/{path_hop["egress_ep"]}' for path_hop in self.path_hops
)
self.uuid = get_uuid_from_string(composed_string)
def convert_explicit_path_hops_to_connections( def convert_explicit_path_hops_to_connections(
path_hops : List[Dict], device_dict : Dict[str, Tuple[Dict, Device]], path_hops : List[Dict], device_dict : Dict[str, Tuple[Dict, Device]],
main_service_uuid : str, main_service_type : ServiceTypeEnum main_service_uuid : str, main_service_type : ServiceTypeEnum
) -> List[Tuple[str, int, List[str], List[str]]]: ) -> List[Tuple[str, int, List[Dict], List[str]]]:
LOGGER.debug('path_hops={:s}'.format(str(path_hops))) LOGGER.debug('path_hops={:s}'.format(str(path_hops)))
connection_stack = queue.LifoQueue() connection_stack = queue.LifoQueue()
connections : List[Tuple[str, int, List[str], List[str]]] = list() connections : List[ConnectionEntry] = list()
prv_device_uuid = None prv_device_uuid = None
prv_res_class : Tuple[Optional[int], Optional[DeviceTypeEnum], Optional[str]] = None, None, None prv_res_class : Tuple[Optional[int], Optional[DeviceTypeEnum], Optional[str]] = None, None, None
...@@ -85,82 +102,82 @@ def convert_explicit_path_hops_to_connections( ...@@ -85,82 +102,82 @@ def convert_explicit_path_hops_to_connections(
LOGGER.debug(' create and terminate underlying connection') LOGGER.debug(' create and terminate underlying connection')
# create underlying connection # create underlying connection
sub_service_uuid = str(uuid.uuid4()) prv_service_type = connection_stack.queue[-1].service_type
prv_service_type = connection_stack.queue[-1][1]
service_type = get_service_type(res_class[1], prv_service_type) service_type = get_service_type(res_class[1], prv_service_type)
connection_stack.put((sub_service_uuid, service_type, [path_hop], [])) connection_entry = ConnectionEntry(service_type=service_type, path_hops=[path_hop])
connection_stack.put(connection_entry)
# underlying connection ended # underlying connection ended
connection = connection_stack.get() connection: ConnectionEntry = connection_stack.get()
connections.append(connection) connections.append(connection)
connection_stack.queue[-1][3].append(connection[0]) connection_stack.queue[-1].dependencies.append(connection)
#connection_stack.queue[-1][2].append(path_hop)
elif prv_res_class[2] is None and res_class[2] is not None: elif prv_res_class[2] is None and res_class[2] is not None:
# entering domain of a device controller, create underlying connection # entering domain of a device controller, create underlying connection
LOGGER.debug(' entering domain of a device controller, create underlying connection') LOGGER.debug(' entering domain of a device controller, create underlying connection')
sub_service_uuid = str(uuid.uuid4()) prv_service_type = connection_stack.queue[-1].service_type
prv_service_type = connection_stack.queue[-1][1]
service_type = get_service_type(res_class[1], prv_service_type) service_type = get_service_type(res_class[1], prv_service_type)
connection_stack.put((sub_service_uuid, service_type, [path_hop], [])) connection_entry = ConnectionEntry(service_type=service_type, path_hops=[path_hop])
connection_stack.put(connection_entry)
elif prv_res_class[2] is not None and res_class[2] is None: elif prv_res_class[2] is not None and res_class[2] is None:
# leaving domain of a device controller, terminate underlying connection # leaving domain of a device controller, terminate underlying connection
LOGGER.debug(' leaving domain of a device controller, terminate underlying connection') LOGGER.debug(' leaving domain of a device controller, terminate underlying connection')
connection = connection_stack.get() connection = connection_stack.get()
connections.append(connection) connections.append(connection)
connection_stack.queue[-1][3].append(connection[0]) connection_stack.queue[-1].dependencies.append(connection)
connection_stack.queue[-1][2].append(path_hop) connection_stack.queue[-1].path_hops.append(path_hop)
elif prv_res_class[2] is not None and res_class[2] is not None: elif prv_res_class[2] is not None and res_class[2] is not None:
if prv_res_class[2] == res_class[2]: if prv_res_class[2] == res_class[2]:
# stay in domain of a device controller, connection continues # stay in domain of a device controller, connection continues
LOGGER.debug(' stay in domain of a device controller, connection continues') LOGGER.debug(' stay in domain of a device controller, connection continues')
connection_stack.queue[-1][2].append(path_hop) connection_stack.queue[-1].path_hops.append(path_hop)
else: else:
# switching to different device controller, chain connections # switching to different device controller, chain connections
LOGGER.debug(' switching to different device controller, chain connections') LOGGER.debug(' switching to different device controller, chain connections')
connection = connection_stack.get() connection = connection_stack.get()
connections.append(connection) connections.append(connection)
connection_stack.queue[-1][3].append(connection[0]) connection_stack.queue[-1].dependencies.append(connection)
sub_service_uuid = str(uuid.uuid4()) prv_service_type = connection_stack.queue[-1].service_type
prv_service_type = connection_stack.queue[-1][1]
service_type = get_service_type(res_class[1], prv_service_type) service_type = get_service_type(res_class[1], prv_service_type)
connection_stack.put((sub_service_uuid, service_type, [path_hop], [])) connection_entry = ConnectionEntry(service_type=service_type, path_hops=[path_hop])
connection_stack.put(connection_entry)
elif prv_res_class[0] is None: elif prv_res_class[0] is None:
# path ingress # path ingress
LOGGER.debug(' path ingress') LOGGER.debug(' path ingress')
connection_stack.put((main_service_uuid, main_service_type, [path_hop], [])) connection_entry = ConnectionEntry(uuid=main_service_uuid, service_type=main_service_type, path_hops=[path_hop])
connection_stack.put(connection_entry)
elif prv_res_class[0] > res_class[0]: elif prv_res_class[0] > res_class[0]:
# create underlying connection # create underlying connection
LOGGER.debug(' create underlying connection') LOGGER.debug(' create underlying connection')
sub_service_uuid = str(uuid.uuid4()) prv_service_type = connection_stack.queue[-1].service_type
prv_service_type = connection_stack.queue[-1][1]
service_type = get_service_type(res_class[1], prv_service_type) service_type = get_service_type(res_class[1], prv_service_type)
connection_stack.put((sub_service_uuid, service_type, [path_hop], [])) connection_entry = ConnectionEntry(service_type=service_type, path_hops=[path_hop])
connection_stack.put(connection_entry)
elif prv_res_class[0] == res_class[0]: elif prv_res_class[0] == res_class[0]:
# same resource group kind # same resource group kind
LOGGER.debug(' same resource group kind') LOGGER.debug(' same resource group kind')
if prv_res_class[1] == res_class[1] and prv_res_class[2] == res_class[2]: if prv_res_class[1] == res_class[1] and prv_res_class[2] == res_class[2]:
# same device type and device controller: connection continues # same device type and device controller: connection continues
LOGGER.debug(' connection continues') LOGGER.debug(' connection continues')
connection_stack.queue[-1][2].append(path_hop) connection_stack.queue[-1].path_hops.append(path_hop)
else: else:
# different device type or device controller: chain connections # different device type or device controller: chain connections
LOGGER.debug(' chain connections') LOGGER.debug(' chain connections')
connection = connection_stack.get() connection = connection_stack.get()
connections.append(connection) connections.append(connection)
connection_stack.queue[-1][3].append(connection[0]) connection_stack.queue[-1].dependencies.append(connection)
sub_service_uuid = str(uuid.uuid4()) prv_service_type = connection_stack.queue[-1].service_type
prv_service_type = connection_stack.queue[-1][1]
service_type = get_service_type(res_class[1], prv_service_type) service_type = get_service_type(res_class[1], prv_service_type)
connection_stack.put((sub_service_uuid, service_type, [path_hop], [])) connection_entry = ConnectionEntry(service_type=service_type, path_hops=[path_hop])
connection_stack.put(connection_entry)
elif prv_res_class[0] < res_class[0]: elif prv_res_class[0] < res_class[0]:
# underlying connection ended # underlying connection ended
LOGGER.debug(' underlying connection ended') LOGGER.debug(' underlying connection ended')
connection = connection_stack.get() connection = connection_stack.get()
connections.append(connection) connections.append(connection)
connection_stack.queue[-1][3].append(connection[0]) connection_stack.queue[-1].dependencies.append(connection)
connection_stack.queue[-1][2].append(path_hop) connection_stack.queue[-1].path_hops.append(path_hop)
else: else:
raise Exception('Uncontrolled condition') raise Exception('Uncontrolled condition')
...@@ -172,7 +189,9 @@ def convert_explicit_path_hops_to_connections( ...@@ -172,7 +189,9 @@ def convert_explicit_path_hops_to_connections(
connections.append(connection_stack.get()) connections.append(connection_stack.get())
LOGGER.debug('connections={:s}'.format(str(connections))) LOGGER.debug('connections={:s}'.format(str(connections)))
assert connection_stack.empty() assert connection_stack.empty()
return connections for c in connections:
c.calculate_subservice_uuid(main_service_uuid)
return [(c.uuid, c.service_type, c.path_hops, [cd.uuid for cd in c.dependencies]) for c in connections]
def convert_explicit_path_hops_to_plain_connection( def convert_explicit_path_hops_to_plain_connection(
path_hops : List[Dict], main_service_uuid : str, main_service_type : ServiceTypeEnum path_hops : List[Dict], main_service_uuid : str, main_service_type : ServiceTypeEnum
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment