Scheduled maintenance on Saturday, 27 September 2025, from 07:00 AM to 4:00 PM GMT (09:00 AM to 6:00 PM CEST) - some services may be unavailable -

Skip to content
Snippets Groups Projects
ComposeRequest.py 6.22 KiB
Newer Older
  • Learn to ignore specific revisions
  • Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    # 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.
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from typing import Dict
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from common.proto.context_pb2 import Constraint, Device, EndPointId, Link, Service, ServiceId, TopologyId
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from common.tools.grpc.Tools import grpc_message_to_json_string
    
    from .Constants import CapacityUnit, LinkForwardingDirection, LinkPortDirection, TerminationDirection, TerminationState
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    def compose_topology_id(topology_id : TopologyId) -> Dict:
        context_uuid = topology_id.context_id.context_uuid.uuid
        topology_uuid = topology_id.topology_uuid.uuid
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        return {'contextId': context_uuid, 'topology_uuid': topology_uuid}
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    def compose_service_id(service_id : ServiceId) -> Dict:
        context_uuid = service_id.context_id.context_uuid.uuid
        service_uuid = service_id.service_uuid.uuid
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        return {'contextId': context_uuid, 'service_uuid': service_uuid}
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    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
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        return {'topology_id': topology_id, 'device_id': device_uuid, 'endpoint_uuid': endpoint_uuid}
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    def compose_capacity(value : str, unit : str) -> Dict:
        return {'total-size': {'value': value, 'unit': unit}}
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    
    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,
        }
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    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}
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    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))
        constraint_type = constraint.custom.constraint_type
        constraint_value = constraint.custom.constraint_value
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        return {'constraint_type': constraint_type, 'constraint_value': constraint_value}
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    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:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            endpoint_id = compose_endpoint_id(device_endpoint.endpoint_id)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            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)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            endpoint = compose_endpoint(
                endpoint_id, endpoint_type, link_port_direction, termination_direction,
                termination_state, total_potential_capacity, available_capacity)
            endpoints.append(endpoint)
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        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
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        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
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        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, algorithm : Dict) -> Dict:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        service_id = compose_service_id(grpc_service.service_id)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        service_type = grpc_service.service_type
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        endpoint_ids = [
            compose_endpoint_id(service_endpoint_id)
            for service_endpoint_id in grpc_service.service_endpoint_ids
        ]
    
        constraints = [
            compose_constraint(service_constraint)
            for service_constraint in grpc_service.service_constraints
        ]
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    
        # algorithm to be executed
        algorithm_id = algorithm.get('id', 'SP')
    
        # if multiple services included in the request, prevent contention
        # If true, services are computed one after the other and resources
        # assigned to service i, are considered as used by services i+1..n
        sync_paths = algorithm.get('sync', False)
    
        k_paths = algorithm.get('k_paths', 1)
    
        return {
            'serviceId': service_id,
            'serviceType': service_type,
            'service_endpoints_ids': endpoint_ids,
            'service_constraints': constraints,
    
            'algId': algorithm_id,
            'syncPaths': sync_paths,
            'kPaths': k_paths,
        }