diff --git a/src/common/tools/context_queries/Context.py b/src/common/tools/context_queries/Context.py index a627b9ba5828d31caca8332d7241d28e126895d3..5e1facf2e077cd043c4ac9193941ac0a47372613 100644 --- a/src/common/tools/context_queries/Context.py +++ b/src/common/tools/context_queries/Context.py @@ -19,12 +19,12 @@ from common.tools.object_factory.Context import json_context from context.client.ContextClient import ContextClient def create_context( - context_client : ContextClient, context_uuid : str + context_client : ContextClient, context_uuid : str, name : Optional[str] = None ) -> None: existing_context_ids = context_client.ListContextIds(Empty()) existing_context_uuids = {context_id.context_uuid.uuid for context_id in existing_context_ids.context_ids} if context_uuid in existing_context_uuids: return - context_client.SetContext(Context(**json_context(context_uuid))) + context_client.SetContext(Context(**json_context(context_uuid, name=name))) def get_context(context_client : ContextClient, context_uuid : str, rw_copy : bool = False) -> Optional[Context]: try: diff --git a/src/common/tools/context_queries/InterDomain.py b/src/common/tools/context_queries/InterDomain.py index 427794c8a408ff038a044f64ec93603f9e606717..aee7cbf7ff496aa8cb90bca62a0af402b6f7be3f 100644 --- a/src/common/tools/context_queries/InterDomain.py +++ b/src/common/tools/context_queries/InterDomain.py @@ -16,12 +16,12 @@ import logging from typing import Dict, List, Set, Tuple from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME from common.DeviceTypes import DeviceTypeEnum -from common.proto.context_pb2 import ContextId, Device, Empty, EndPointId, ServiceTypeEnum, Slice +from common.proto.context_pb2 import ContextId, Empty, EndPointId, ServiceTypeEnum, Slice from common.proto.pathcomp_pb2 import PathCompRequest -from common.tools.context_queries.CheckType import device_type_is_network -from common.tools.context_queries.Device import get_devices_in_topology -from common.tools.context_queries.Topology import get_topology -from common.tools.grpc.Tools import grpc_message_to_json_string +from .CheckType import device_type_is_network +from .Device import get_device #, get_devices_in_topology +from .Topology import get_topology +from common.tools.grpc.Tools import grpc_message_list_to_json, grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient from pathcomp.frontend.client.PathCompClient import PathCompClient @@ -41,7 +41,11 @@ def get_local_device_uuids(context_client : ContextClient) -> Set[str]: topology_name = topology.name if topology_name == INTERDOMAIN_TOPOLOGY_NAME: continue local_topologies[topology_uuid] = topology - LOGGER.debug('[get_local_device_uuids] local_topologies={:s}'.format(str(local_topologies))) + str_local_topologies = { + topology_uuid:grpc_message_to_json_string(topology) + for topology_uuid,topology in local_topologies.items() + } + LOGGER.debug('[get_local_device_uuids] local_topologies={:s}'.format(str(str_local_topologies))) local_topology_uuids = set(local_topologies.keys()) LOGGER.debug('[get_local_device_uuids] local_topology_uuids={:s}'.format(str(local_topology_uuids))) @@ -79,17 +83,6 @@ def get_interdomain_device_uuids(context_client : ContextClient) -> Set[str]: LOGGER.debug('[get_interdomain_device_uuids] interdomain_device_uuids={:s}'.format(str(interdomain_device_uuids))) return interdomain_device_uuids -#def get_local_domain_devices(context_client : ContextClient) -> List[Device]: -# local_device_uuids = get_local_device_uuids(context_client) -# all_devices = context_client.ListDevices(Empty()) -# local_domain_devices = list() -# for device in all_devices.devices: -# if not device_type_is_network(device.device_type): continue -# device_uuid = device.device_id.device_uuid.uuid -# if device_uuid not in local_device_uuids: continue -# local_domain_devices.append(device) -# return local_domain_devices - def is_inter_domain(context_client : ContextClient, endpoint_ids : List[EndPointId]) -> bool: interdomain_device_uuids = get_interdomain_device_uuids(context_client) LOGGER.debug('[is_inter_domain] interdomain_device_uuids={:s}'.format(str(interdomain_device_uuids))) @@ -107,93 +100,22 @@ def is_inter_domain(context_client : ContextClient, endpoint_ids : List[EndPoint LOGGER.debug('[is_inter_domain] is_inter_domain={:s}'.format(str(is_inter_domain_))) return is_inter_domain_ -#def is_multi_domain(context_client : ContextClient, endpoint_ids : List[EndPointId]) -> bool: -# local_device_uuids = get_local_device_uuids(context_client) -# LOGGER.debug('[is_multi_domain] local_device_uuids={:s}'.format(str(local_device_uuids))) -# remote_endpoint_ids = [ -# endpoint_id -# for endpoint_id in endpoint_ids -# if endpoint_id.device_id.device_uuid.uuid not in local_device_uuids -# ] -# str_remote_endpoint_ids = [ -# (endpoint_id.device_id.device_uuid.uuid, endpoint_id.endpoint_uuid.uuid) -# for endpoint_id in remote_endpoint_ids -# ] -# LOGGER.debug('[is_multi_domain] remote_endpoint_ids={:s}'.format(str(str_remote_endpoint_ids))) -# is_multi_domain_ = len(remote_endpoint_ids) > 0 -# LOGGER.debug('[is_multi_domain] is_multi_domain={:s}'.format(str(is_multi_domain_))) -# return is_multi_domain_ - -def compute_interdomain_path( - pathcomp_client : PathCompClient, slice_ : Slice -) -> List[Tuple[str, List[EndPointId]]]: - context_uuid = slice_.slice_id.context_id.context_uuid.uuid - slice_uuid = slice_.slice_id.slice_uuid.uuid - - pathcomp_req = PathCompRequest() - pathcomp_req.shortest_path.Clear() # pylint: disable=no-member - pathcomp_req_svc = pathcomp_req.services.add() # pylint: disable=no-member - pathcomp_req_svc.service_id.context_id.context_uuid.uuid = context_uuid - pathcomp_req_svc.service_id.service_uuid.uuid = slice_uuid - pathcomp_req_svc.service_type = ServiceTypeEnum.SERVICETYPE_L2NM - - for endpoint_id in slice_.slice_endpoint_ids: - service_endpoint_id = pathcomp_req_svc.service_endpoint_ids.add() - service_endpoint_id.CopyFrom(endpoint_id) - - constraint_sla_capacity = pathcomp_req_svc.service_constraints.add() - constraint_sla_capacity.sla_capacity.capacity_gbps = 10.0 - - constraint_sla_latency = pathcomp_req_svc.service_constraints.add() - constraint_sla_latency.sla_latency.e2e_latency_ms = 100.0 - - LOGGER.debug('pathcomp_req = {:s}'.format(grpc_message_to_json_string(pathcomp_req))) - pathcomp_rep = pathcomp_client.Compute(pathcomp_req) - LOGGER.debug('pathcomp_rep = {:s}'.format(grpc_message_to_json_string(pathcomp_rep))) - - service = next(iter([ - service - for service in pathcomp_rep.services - if service.service_id.service_uuid.uuid == pathcomp_req_svc.service_id.service_uuid.uuid - ]), None) - if service is None: - str_service_id = grpc_message_to_json_string(pathcomp_req_svc.service_id) - raise Exception('Service({:s}) not found'.format(str_service_id)) - - connection = next(iter([ - connection - for connection in pathcomp_rep.connections - if connection.service_id.service_uuid.uuid == pathcomp_req_svc.service_id.service_uuid.uuid - ]), None) - if connection is None: - str_service_id = grpc_message_to_json_string(pathcomp_req_svc.service_id) - raise Exception('Connection for Service({:s}) not found'.format(str_service_id)) - - domain_list : List[str] = list() - domain_to_endpoint_ids : Dict[str, List[EndPointId]] = dict() - for endpoint_id in connection.path_hops_endpoint_ids: - device_uuid = endpoint_id.device_id.device_uuid.uuid - #endpoint_uuid = endpoint_id.endpoint_uuid.uuid - if device_uuid not in domain_to_endpoint_ids: domain_list.append(device_uuid) - domain_to_endpoint_ids.setdefault(device_uuid, []).append(endpoint_id) - - return [ - (domain_uuid, domain_to_endpoint_ids.get(domain_uuid)) - for domain_uuid in domain_list - ] - def get_device_to_domain_map(context_client : ContextClient) -> Dict[str, str]: devices_to_domains : Dict[str, str] = dict() contexts = context_client.ListContexts(Empty()) for context in contexts.contexts: context_id = context.context_id context_uuid = context_id.context_uuid.uuid + context_name = context.name topologies = context_client.ListTopologies(context_id) - if context_uuid == DEFAULT_CONTEXT_NAME: + if (context_uuid == DEFAULT_CONTEXT_NAME) or (context_name == DEFAULT_CONTEXT_NAME): for topology in topologies.topologies: topology_id = topology.topology_id topology_uuid = topology_id.topology_uuid.uuid + topology_name = topology.name + if topology_uuid in {DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME}: continue + if topology_name in {DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME}: continue # add topology names except DEFAULT_TOPOLOGY_NAME and INTERDOMAIN_TOPOLOGY_NAME; they are # abstracted as a local device in inter-domain and the name of the topology is used as @@ -209,9 +131,11 @@ def get_device_to_domain_map(context_client : ContextClient) -> Dict[str, str]: for topology in topologies.topologies: topology_id = topology.topology_id topology_uuid = topology_id.topology_uuid.uuid + topology_name = topology.name # if topology is not interdomain if topology_uuid in {INTERDOMAIN_TOPOLOGY_NAME}: continue + if topology_name in {INTERDOMAIN_TOPOLOGY_NAME}: continue # add devices to the remote domain list for device_id in topology.device_ids: @@ -220,40 +144,117 @@ def get_device_to_domain_map(context_client : ContextClient) -> Dict[str, str]: return devices_to_domains -def compute_traversed_domains( - context_client : ContextClient, interdomain_path : List[Tuple[str, List[EndPointId]]] -) -> List[Tuple[str, bool, List[EndPointId]]]: +def compute_interdomain_sub_slices( + context_client : ContextClient, pathcomp_client : PathCompClient, slice_ : Slice +) -> Tuple[Dict[str, List[EndPointId]], Dict[str, List[EndPointId]]]: + context_uuid = slice_.slice_id.context_id.context_uuid.uuid + slice_uuid = slice_.slice_id.slice_uuid.uuid + + pathcomp_req = PathCompRequest() + pathcomp_req.shortest_path.Clear() # pylint: disable=no-member + pathcomp_req_svc = pathcomp_req.services.add() # pylint: disable=no-member + pathcomp_req_svc.service_id.context_id.context_uuid.uuid = context_uuid + pathcomp_req_svc.service_id.service_uuid.uuid = slice_uuid + pathcomp_req_svc.service_type = ServiceTypeEnum.SERVICETYPE_L2NM + + for endpoint_id in slice_.slice_endpoint_ids: + service_endpoint_id = pathcomp_req_svc.service_endpoint_ids.add() + service_endpoint_id.CopyFrom(endpoint_id) + + capacity_gbps = 10.0 # default value; to be overwritten by constraints in slice + e2e_latency_ms = 100.0 # default value; to be overwritten by constraints in slice + for constraint in slice_.slice_constraints: + kind = constraint.WhichOneof('constraint') + if kind == 'sla_capacity': + capacity_gbps = constraint.sla_capacity.capacity_gbps + elif kind == 'sla_latency': + e2e_latency_ms = constraint.sla_latency.e2e_latency_ms + + constraint_sla_capacity = pathcomp_req_svc.service_constraints.add() + constraint_sla_capacity.sla_capacity.capacity_gbps = capacity_gbps + + constraint_sla_latency = pathcomp_req_svc.service_constraints.add() + constraint_sla_latency.sla_latency.e2e_latency_ms = e2e_latency_ms + + LOGGER.debug('[compute_interdomain_sub_slices] pathcomp_req = {:s}'.format( + grpc_message_to_json_string(pathcomp_req))) + pathcomp_rep = pathcomp_client.Compute(pathcomp_req) + LOGGER.debug('[compute_interdomain_sub_slices] pathcomp_rep = {:s}'.format( + grpc_message_to_json_string(pathcomp_rep))) + + num_services = len(pathcomp_rep.services) + if num_services == 0: + raise Exception('No services received : {:s}'.format(grpc_message_to_json_string(pathcomp_rep))) + + num_connections = len(pathcomp_rep.connections) + if num_connections != num_services: + raise Exception('No connections received : {:s}'.format(grpc_message_to_json_string(pathcomp_rep))) local_device_uuids = get_local_device_uuids(context_client) - LOGGER.debug('[compute_traversed_domains] local_device_uuids={:s}'.format(str(local_device_uuids))) - - #interdomain_devices = get_devices_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) - #interdomain_devices = { - # device.device_id.device_uuid.uuid : device - # for device in interdomain_devices - #} - - devices_to_domains = get_device_to_domain_map(context_client) - LOGGER.debug('[compute_traversed_domains] devices_to_domains={:s}'.format(str(devices_to_domains))) - - traversed_domains : List[Tuple[str, bool, List[EndPointId]]] = list() - domains_dict : Dict[str, Tuple[str, bool, List[EndPointId]]] = dict() - for device_uuid, endpoint_ids in interdomain_path: - domain_uuid = devices_to_domains.get(device_uuid, '---') - domain = domains_dict.get(domain_uuid) - if domain is None: - is_local_domain = domain_uuid in local_device_uuids - domain = (domain_uuid, is_local_domain, []) - traversed_domains.append(domain) - domains_dict[domain_uuid] = domain - domain[2].extend(endpoint_ids) - - str_traversed_domains = [ - (domain_uuid, is_local_domain, [ - (endpoint_id.device_id.device_uuid.uuid, endpoint_id.endpoint_uuid.uuid) - for endpoint_id in endpoint_ids - ]) - for domain_uuid,is_local_domain,endpoint_ids in traversed_domains - ] - LOGGER.debug('[compute_traversed_domains] devices_to_domains={:s}'.format(str(str_traversed_domains))) - return traversed_domains + LOGGER.debug('[compute_interdomain_sub_slices] local_device_uuids={:s}'.format(str(local_device_uuids))) + + device_to_domain_map = get_device_to_domain_map(context_client) + LOGGER.debug('[compute_interdomain_sub_slices] device_to_domain_map={:s}'.format(str(device_to_domain_map))) + + local_slices : Dict[str, List[EndPointId]] = dict() + remote_slices : Dict[str, List[EndPointId]] = dict() + req_service_uuid = pathcomp_req_svc.service_id.service_uuid.uuid + for service in pathcomp_rep.services: + service_uuid = service.service_id.service_uuid.uuid + if service_uuid == req_service_uuid: continue # main synthetic service; we don't care + device_uuids = { + endpoint_id.device_id.device_uuid.uuid + for endpoint_id in service.service_endpoint_ids + } + + local_domain_uuids = set() + remote_domain_uuids = set() + for device_uuid in device_uuids: + if device_uuid in local_device_uuids: + domain_uuid = device_to_domain_map.get(device_uuid) + if domain_uuid is None: + raise Exception('Unable to map device({:s}) to a domain'.format(str(device_uuid))) + local_domain_uuids.add(domain_uuid) + else: + device = get_device( + context_client, device_uuid, include_endpoints=True, include_config_rules=False, + include_components=False) + if device is None: raise Exception('Device({:s}) not found'.format(str(device_uuid))) + if not device_type_is_network(device.device_type): + MSG = 'Weird device({:s}) is not local and not network' + raise Exception(MSG.format(grpc_message_to_json_string(device))) + remote_domain_uuids.add(device_uuid) + + if len(local_domain_uuids) > 1: + MSG = 'Devices({:s}) map to multiple local domains({:s})' + raise Exception(MSG.format(str(device_uuids), str(local_domain_uuids))) + is_local = len(local_domain_uuids) == 1 + + if len(remote_domain_uuids) > 1: + MSG = 'Devices({:s}) map to multiple remote domains({:s})' + raise Exception(MSG.format(str(device_uuids), str(remote_domain_uuids))) + is_remote = len(remote_domain_uuids) == 1 + + if is_local == is_remote: + MSG = 'Weird service combines local and remote devices: {:s}' + raise Exception(MSG.format(grpc_message_to_json_string(service))) + elif is_local: + local_domain_uuid = local_domain_uuids.pop() + local_slices.setdefault(local_domain_uuid, list()).append(service.service_endpoint_ids) + else: + remote_domain_uuid = remote_domain_uuids.pop() + remote_slices.setdefault(remote_domain_uuid, list()).append(service.service_endpoint_ids) + + str_local_slices = { + domain_uuid:grpc_message_list_to_json(endpoint_ids) + for domain_uuid,endpoint_ids in local_slices.items() + } + LOGGER.debug('[compute_interdomain_sub_slices] local_slices={:s}'.format(str(str_local_slices))) + + str_remote_slices = { + domain_uuid:grpc_message_list_to_json(endpoint_ids) + for domain_uuid,endpoint_ids in remote_slices.items() + } + LOGGER.debug('[compute_interdomain_sub_slices] remote_slices={:s}'.format(str(str_remote_slices))) + + return local_slices, remote_slices diff --git a/src/common/tools/context_queries/InterDomain_old.py b/src/common/tools/context_queries/InterDomain_old.py new file mode 100644 index 0000000000000000000000000000000000000000..ef4f6aa808696d7290a2c80220c3212d3e586307 --- /dev/null +++ b/src/common/tools/context_queries/InterDomain_old.py @@ -0,0 +1,143 @@ +# 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. + +from common.tools.context_queries.Device import get_device #, get_devices_in_topology + +## DEPRECATED +#def get_local_domain_devices(context_client : ContextClient) -> List[Device]: +# local_device_uuids = get_local_device_uuids(context_client) +# all_devices = context_client.ListDevices(Empty()) +# local_domain_devices = list() +# for device in all_devices.devices: +# if not device_type_is_network(device.device_type): continue +# device_uuid = device.device_id.device_uuid.uuid +# if device_uuid not in local_device_uuids: continue +# local_domain_devices.append(device) +# return local_domain_devices + +## DEPRECATED +#def is_multi_domain(context_client : ContextClient, endpoint_ids : List[EndPointId]) -> bool: +# local_device_uuids = get_local_device_uuids(context_client) +# LOGGER.debug('[is_multi_domain] local_device_uuids={:s}'.format(str(local_device_uuids))) +# remote_endpoint_ids = [ +# endpoint_id +# for endpoint_id in endpoint_ids +# if endpoint_id.device_id.device_uuid.uuid not in local_device_uuids +# ] +# str_remote_endpoint_ids = [ +# (endpoint_id.device_id.device_uuid.uuid, endpoint_id.endpoint_uuid.uuid) +# for endpoint_id in remote_endpoint_ids +# ] +# LOGGER.debug('[is_multi_domain] remote_endpoint_ids={:s}'.format(str(str_remote_endpoint_ids))) +# is_multi_domain_ = len(remote_endpoint_ids) > 0 +# LOGGER.debug('[is_multi_domain] is_multi_domain={:s}'.format(str(is_multi_domain_))) +# return is_multi_domain_ + +## DEPRECATED +#def compute_interdomain_path( +# pathcomp_client : PathCompClient, slice_ : Slice +#) -> List[Tuple[str, List[EndPointId]]]: +# context_uuid = slice_.slice_id.context_id.context_uuid.uuid +# slice_uuid = slice_.slice_id.slice_uuid.uuid +# +# pathcomp_req = PathCompRequest() +# pathcomp_req.shortest_path.Clear() # pylint: disable=no-member +# pathcomp_req_svc = pathcomp_req.services.add() # pylint: disable=no-member +# pathcomp_req_svc.service_id.context_id.context_uuid.uuid = context_uuid +# pathcomp_req_svc.service_id.service_uuid.uuid = slice_uuid +# pathcomp_req_svc.service_type = ServiceTypeEnum.SERVICETYPE_L2NM +# +# for endpoint_id in slice_.slice_endpoint_ids: +# service_endpoint_id = pathcomp_req_svc.service_endpoint_ids.add() +# service_endpoint_id.CopyFrom(endpoint_id) +# +# constraint_sla_capacity = pathcomp_req_svc.service_constraints.add() +# constraint_sla_capacity.sla_capacity.capacity_gbps = 10.0 +# +# constraint_sla_latency = pathcomp_req_svc.service_constraints.add() +# constraint_sla_latency.sla_latency.e2e_latency_ms = 100.0 +# +# LOGGER.debug('pathcomp_req = {:s}'.format(grpc_message_to_json_string(pathcomp_req))) +# pathcomp_rep = pathcomp_client.Compute(pathcomp_req) +# LOGGER.debug('pathcomp_rep = {:s}'.format(grpc_message_to_json_string(pathcomp_rep))) +# +# service = next(iter([ +# service +# for service in pathcomp_rep.services +# if service.service_id.service_uuid.uuid == pathcomp_req_svc.service_id.service_uuid.uuid +# ]), None) +# if service is None: +# str_service_id = grpc_message_to_json_string(pathcomp_req_svc.service_id) +# raise Exception('Service({:s}) not found'.format(str_service_id)) +# +# connection = next(iter([ +# connection +# for connection in pathcomp_rep.connections +# if connection.service_id.service_uuid.uuid == pathcomp_req_svc.service_id.service_uuid.uuid +# ]), None) +# if connection is None: +# str_service_id = grpc_message_to_json_string(pathcomp_req_svc.service_id) +# raise Exception('Connection for Service({:s}) not found'.format(str_service_id)) +# +# domain_list : List[str] = list() +# domain_to_endpoint_ids : Dict[str, List[EndPointId]] = dict() +# for endpoint_id in connection.path_hops_endpoint_ids: +# device_uuid = endpoint_id.device_id.device_uuid.uuid +# #endpoint_uuid = endpoint_id.endpoint_uuid.uuid +# if device_uuid not in domain_to_endpoint_ids: domain_list.append(device_uuid) +# domain_to_endpoint_ids.setdefault(device_uuid, []).append(endpoint_id) +# +# return [ +# (domain_uuid, domain_to_endpoint_ids.get(domain_uuid)) +# for domain_uuid in domain_list +# ] + +## DEPRECATED +#def compute_traversed_domains( +# context_client : ContextClient, interdomain_path : List[Tuple[str, List[EndPointId]]] +#) -> List[Tuple[str, bool, List[EndPointId]]]: +# +# local_device_uuids = get_local_device_uuids(context_client) +# LOGGER.debug('[compute_traversed_domains] local_device_uuids={:s}'.format(str(local_device_uuids))) +# +# #interdomain_devices = get_devices_in_topology(context_client, ADMIN_CONTEXT_ID, INTERDOMAIN_TOPOLOGY_NAME) +# #interdomain_devices = { +# # device.device_id.device_uuid.uuid : device +# # for device in interdomain_devices +# #} +# +# devices_to_domains = get_device_to_domain_map(context_client) +# LOGGER.debug('[compute_traversed_domains] devices_to_domains={:s}'.format(str(devices_to_domains))) +# +# traversed_domains : List[Tuple[str, bool, List[EndPointId]]] = list() +# domains_dict : Dict[str, Tuple[str, bool, List[EndPointId]]] = dict() +# for device_uuid, endpoint_ids in interdomain_path: +# domain_uuid = devices_to_domains.get(device_uuid, '---') +# domain = domains_dict.get(domain_uuid) +# if domain is None: +# is_local_domain = domain_uuid in local_device_uuids +# domain = (domain_uuid, is_local_domain, []) +# traversed_domains.append(domain) +# domains_dict[domain_uuid] = domain +# domain[2].extend(endpoint_ids) +# +# str_traversed_domains = [ +# (domain_uuid, is_local_domain, [ +# (endpoint_id.device_id.device_uuid.uuid, endpoint_id.endpoint_uuid.uuid) +# for endpoint_id in endpoint_ids +# ]) +# for domain_uuid,is_local_domain,endpoint_ids in traversed_domains +# ] +# LOGGER.debug('[compute_traversed_domains] devices_to_domains={:s}'.format(str(str_traversed_domains))) +# return traversed_domains