# 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 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 .ConstantsMappings import ( CapacityUnit, LinkForwardingDirection, LinkPortDirection, TerminationDirection, TerminationState) LOGGER = logging.getLogger(__name__) 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} def compose_endpoint_id(endpoint_id : EndPointId) -> Dict: topology_id = compose_topology_id(endpoint_id.topology_id) device_uuid = endpoint_id.device_id.device_uuid.uuid endpoint_uuid = endpoint_id.endpoint_uuid.uuid return {'topology_id': topology_id, 'device_id': device_uuid, 'endpoint_uuid': endpoint_uuid} def compose_capacity(value : str, unit : str) -> Dict: return {'total-size': {'value': value, 'unit': unit}} def compose_endpoint( endpoint_id : Dict, endpoint_type : str, link_port_direction : int, termination_direction : int, termination_state : int, total_potential_capacity : Dict, available_capacity : Dict ) -> Dict: return { 'endpoint_id': endpoint_id, 'endpoint_type': endpoint_type, 'link_port_direction': link_port_direction, 'termination-direction': termination_direction, 'termination-state': termination_state, 'total-potential-capacity': total_potential_capacity, 'available-capacity': available_capacity, } def compose_cost_characteristics(cost_name : str, cost_value : str, cost_algorithm : str) -> Dict: return {'cost-name': cost_name, 'cost-value': cost_value, 'cost-algorithm': cost_algorithm} def compose_latency_characteristics(fixed_latency_characteristic : str) -> Dict: return {'fixed-latency-characteristic': fixed_latency_characteristic} def compose_constraint(constraint : Constraint) -> Dict: if constraint.WhichOneof('constraint') != 'custom': str_constraint = grpc_message_to_json_string(constraint) LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint)) return None constraint_type = constraint.custom.constraint_type if constraint_type in {'diversity'}: str_constraint = grpc_message_to_json_string(constraint) LOGGER.warning('Ignoring unsupported Constraint({:s})'.format(str_constraint)) return None constraint_value = constraint.custom.constraint_value return {'constraint_type': constraint_type, 'constraint_value': constraint_value} def compose_device(grpc_device : Device) -> Dict: device_uuid = grpc_device.device_id.device_uuid.uuid device_type = grpc_device.device_type endpoints = [] for device_endpoint in grpc_device.device_endpoints: endpoint_id = compose_endpoint_id(device_endpoint.endpoint_id) endpoint_type = device_endpoint.endpoint_type link_port_direction = LinkPortDirection.BIDIRECTIONAL.value termination_direction = TerminationDirection.BIDIRECTIONAL.value termination_state = TerminationState.TERMINATED_BIDIRECTIONAL.value total_potential_capacity = compose_capacity(200, CapacityUnit.MBPS.value) available_capacity = compose_capacity(200, CapacityUnit.MBPS.value) endpoint = compose_endpoint( endpoint_id, endpoint_type, link_port_direction, termination_direction, termination_state, total_potential_capacity, available_capacity) endpoints.append(endpoint) return {'device_Id': device_uuid, 'device_type': device_type, 'device_endpoints': endpoints} def compose_link(grpc_link : Link) -> Dict: link_uuid = grpc_link.link_id.link_uuid.uuid endpoint_ids = [ {'endpoint_id' : compose_endpoint_id(link_endpoint_id)} for link_endpoint_id in grpc_link.link_endpoint_ids ] forwarding_direction = LinkForwardingDirection.BIDIRECTIONAL.value total_potential_capacity = compose_capacity(200, CapacityUnit.MBPS.value) available_capacity = compose_capacity(200, CapacityUnit.MBPS.value) cost_characteristics = compose_cost_characteristics('linkcost', '1', '0') latency_characteristics = compose_latency_characteristics('2') return { 'link_Id': link_uuid, 'link_endpoint_ids': endpoint_ids, 'forwarding_direction': forwarding_direction, 'total-potential-capacity': total_potential_capacity, 'available-capacity': available_capacity, 'cost-characteristics': cost_characteristics, 'latency-characteristics': latency_characteristics, } def compose_service(grpc_service : Service) -> Dict: service_id = compose_service_id(grpc_service.service_id) service_type = grpc_service.service_type endpoint_ids = [ compose_endpoint_id(service_endpoint_id) for service_endpoint_id in grpc_service.service_endpoint_ids ] constraints = list(filter(lambda constraint: constraint is not None, [ compose_constraint(service_constraint) for service_constraint in grpc_service.service_constraints ])) constraint_types = {constraint['constraint_type'] for constraint in constraints} if 'bandwidth[gbps]' not in constraint_types: constraints.append({'constraint_type': 'bandwidth[gbps]', 'constraint_value': '20.0'}) if 'latency[ms]' not in constraint_types: constraints.append({'constraint_type': 'latency[ms]', 'constraint_value': '20.0'}) return { 'serviceId': service_id, 'serviceType': service_type, 'service_endpoints_ids': endpoint_ids, 'service_constraints': constraints, }