X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=RO-SDN-tapi%2Fosm_rosdn_tapi%2Fservices_composer.py;fp=RO-SDN-tapi%2Fosm_rosdn_tapi%2Fservices_composer.py;h=720e4230d2f412d82864e2c4d91d3c629ec23c76;hb=210ec7ca0dc0df57a9302486eedea70f9afafb18;hp=0000000000000000000000000000000000000000;hpb=ce61568d0ed0ed91ff684761b3e97102dd4e8883;p=osm%2FRO.git diff --git a/RO-SDN-tapi/osm_rosdn_tapi/services_composer.py b/RO-SDN-tapi/osm_rosdn_tapi/services_composer.py new file mode 100644 index 00000000..720e4230 --- /dev/null +++ b/RO-SDN-tapi/osm_rosdn_tapi/services_composer.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- + +####################################################################################### +# This file is part of OSM RO module +# +# Copyright ETSI Contributors and Others. +# +# 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. +####################################################################################### +# This work has been performed in the context of the TeraFlow Project - +# funded by the European Commission under Grant number 101015857 through the +# Horizon 2020 program. +# Contributors: +# - Lluis Gifre +# - Ricard Vilalta +####################################################################################### + +"""This file contains the ServiceComposer class used by the Transport API (TAPI) WIM +connector to compose the services based on the service_endpoint_ids and their +directionality.""" + +from .exceptions import ( + WimTapiIncongruentDirectionality, + WimTapiIncongruentEndPoints, + WimTapiMissingMappingField, + WimTapiSipNotFound, +) +from .message_composers import ( + compose_endpoint, + compose_requested_capacity, + # compose_vlan_constraint, +) + + +class ServicesComposer: + def __init__(self, service_interface_points) -> None: + self.sips = service_interface_points + + # if unidirectional + # - a single service_endpoint item is created + # - the service_endpoint item contains with the 2 bidirectional SIPs + # if bidirectional + # - two service_endpoint items are created + # - each service_endpoint item containing a list of 2 unidirectional SIPs (in, out) + self.services = list() + + # TODO: populate dynamically capacity of the connection + self.requested_capacity = compose_requested_capacity(1, unit="GBPS") + + self.vlan_constraint = None + # TODO: VLAN needs to be processed by connection point; by now deactivated + # if connection_point.get("service_endpoint_encapsulation_type") == "dot1q": + # encap_info = connection_point.get("service_endpoint_encapsulation_info", {}) + # vlan_id = encap_info.get("vlan") + # if vlan_id is not None: + # vlan_constraint = compose_vlan_constraint(vlan_id) + + def add_bidirectional(self, service_endpoint_id): + if len(self.services) == 0: + # assume bidirectional, SIP is service_endpoint_id + service_interface_point = self.sips[service_endpoint_id] + self.services.append([compose_endpoint(service_interface_point)]) + elif len(self.services) == 1: + # is bidirectional, SIP is service_endpoint_id + if len(self.services[0]) > 1: + # too much endpoints per service + raise WimTapiIncongruentEndPoints(self.services, service_endpoint_id) + self.services[0].append(compose_endpoint(self.sips[service_endpoint_id])) + else: + raise WimTapiIncongruentDirectionality(self.services, service_endpoint_id) + + def add_unidirectional(self, service_endpoint_id, sip_input, sip_output): + if len(self.services) == 0: + # assume unidirectional + self.services.append([compose_endpoint(self.sips[sip_output])]) # AZ + self.services.append([compose_endpoint(self.sips[sip_input])]) # ZA + elif len(self.services) == 2: + # is unidirectional + + if len(self.services[0]) > 1: + # too much endpoints per service + raise WimTapiIncongruentEndPoints(self.services[0], service_endpoint_id) + self.services[0].append(compose_endpoint(self.sips[sip_input])) # AZ + + if len(self.services[1]) > 1: + # too much endpoints per service + raise WimTapiIncongruentEndPoints(self.services[1], service_endpoint_id) + self.services[1].insert(0, compose_endpoint(self.sips[sip_output])) # ZA + else: + raise WimTapiIncongruentDirectionality(self.services, service_endpoint_id) + + def add_service_endpoint(self, service_endpoint_id, mapping): + service_mapping_info = mapping.get("service_mapping_info", {}) + + if ( + len(service_mapping_info) == 0 + or "sip_input" not in service_mapping_info + or "sip_output" not in service_mapping_info + ): + # bidirectional (no mapping or no sip_input or no sip_output) + if service_endpoint_id not in self.sips: + raise WimTapiSipNotFound(service_endpoint_id, self.sips) + self.add_bidirectional(service_endpoint_id) + + else: + # unidirectional, sip_input and sip_output provided in mapping + + sip_input = service_mapping_info.get("sip_input") + if sip_input is None: + raise WimTapiMissingMappingField( + mapping, "service_mapping_info.sip_input" + ) + + if sip_input not in self.sips: + raise WimTapiSipNotFound(sip_input, self.sips) + + sip_output = service_mapping_info.get("sip_output") + if sip_output is None: + raise WimTapiMissingMappingField( + mapping, "service_mapping_info.sip_output" + ) + + if sip_output not in self.sips: + raise WimTapiSipNotFound(sip_output, self.sips) + + self.add_unidirectional(service_endpoint_id, sip_input, sip_output) + + def is_bidirectional(self): + return len(self.services) == 1 + + def dump(self, logger): + str_data = "\n".join( + [ + "services_composer {", + " services={:s}".format(str(self.services)), + " requested_capacity={:s}".format(str(self.requested_capacity)), + " vlan_constraint={:s}".format(str(self.vlan_constraint)), + "}", + ] + ) + logger.debug(str_data)