Loading src/context/service/database/Link.py +5 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ from .models.TopologyModel import TopologyLinkModel, TopologyModel from .uuids.EndPoint import endpoint_get_uuid from .uuids.Link import link_get_uuid from .Events import notify_event_context, notify_event_link, notify_event_topology from .models.enums.LinkType import grpc_to_enum__link_type_enum LOGGER = logging.getLogger(__name__) Loading Loading @@ -67,8 +68,8 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link) raw_link_name = request.name link_name = raw_link_uuid if len(raw_link_name) == 0 else raw_link_name link_uuid = link_get_uuid(request.link_id, link_name=link_name, allow_random=True) now = datetime.datetime.utcnow() link_type = grpc_to_enum__link_type_enum(request.link_type) now = datetime.datetime.now(datetime.timezone.utc) topology_uuids : Set[str] = set() related_topologies : List[Dict] = list() Loading Loading @@ -117,6 +118,7 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link) link_data = [{ 'link_uuid' : link_uuid, 'link_name' : link_name, 'link_type' : link_type, 'total_capacity_gbps' : total_capacity_gbps, 'used_capacity_gbps' : used_capacity_gbps, 'created_at' : now, Loading @@ -129,6 +131,7 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link) index_elements=[LinkModel.link_uuid], set_=dict( link_name = stmt.excluded.link_name, link_type = stmt.excluded.link_type, total_capacity_gbps = stmt.excluded.total_capacity_gbps, used_capacity_gbps = stmt.excluded.used_capacity_gbps, updated_at = stmt.excluded.updated_at, Loading src/context/service/database/models/LinkModel.py +7 −1 Original line number Diff line number Diff line Loading @@ -13,17 +13,20 @@ # limitations under the License. import operator from sqlalchemy import CheckConstraint, Column, DateTime, Float, ForeignKey, Integer, String from sqlalchemy import CheckConstraint, Column, DateTime, Enum, Float, ForeignKey, Integer, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from typing import Dict from ._Base import _Base from common.proto.context_pb2 import LinkTypeEnum from .enums.LinkType import ORM_LinkTypeEnum class LinkModel(_Base): __tablename__ = 'link' link_uuid = Column(UUID(as_uuid=False), primary_key=True) link_name = Column(String, nullable=False) link_type = Column(Enum(ORM_LinkTypeEnum), nullable=False) total_capacity_gbps = Column(Float, nullable=True) used_capacity_gbps = Column(Float, nullable=True) created_at = Column(DateTime, nullable=False) Loading @@ -44,11 +47,14 @@ class LinkModel(_Base): result = { 'link_id' : self.dump_id(), 'name' : self.link_name, 'link_type' : self.link_type.value, 'link_endpoint_ids': [ link_endpoint.endpoint.dump_id() for link_endpoint in sorted(self.link_endpoints, key=operator.attrgetter('position')) ], } if self.link_type is None: self.link_type = LinkTypeEnum.LINKTYPE_UNKNOWN if self.total_capacity_gbps is not None: attributes : Dict = result.setdefault('attributes', dict()) attributes.setdefault('total_capacity_gbps', self.total_capacity_gbps) Loading src/context/service/database/models/enums/LinkType.py 0 → 100644 +32 −0 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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. import enum, functools from common.proto.context_pb2 import LinkTypeEnum from ._GrpcToEnum import grpc_to_enum # IMPORTANT: Entries of enum class ORM_DeviceDriverEnum should be named as in # the proto files removing the prefixes. For example, proto item # DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG should be included as # OPENCONFIG. If item name does not match, automatic mapping of # proto enums to database enums will fail. class ORM_LinkTypeEnum(enum.Enum): UNKNOWN = LinkTypeEnum.LINKTYPE_UNKNOWN COPPER = LinkTypeEnum.LINKTYPE_COPPER VIRTUAL_COPPER = LinkTypeEnum.LINKTYPE_VIRTUAL_COPPER OPTICAL = LinkTypeEnum.LINKTYPE_OPTICAL VIRTUAL_OPTICAL = LinkTypeEnum.LINKTYPE_VIRTUAL_OPTICAL grpc_to_enum__link_type_enum = functools.partial( grpc_to_enum, LinkTypeEnum, ORM_LinkTypeEnum) src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +13 −9 Original line number Diff line number Diff line Loading @@ -80,7 +80,6 @@ class SubscriptionServer(Thread): LOGGER.debug("Received message from WebSocket: {}".format(message)) except Exception as ex: LOGGER.error('Exception receiving from WebSocket: {}'.format(ex)) self._events_server() Loading @@ -99,12 +98,13 @@ class SubscriptionServer(Thread): def _event_received(self, connection): LOGGER.debug('Event received') for message in connection: message_json = json.loads(message) # LOGGER.info("message_json: {}".format(message_json)) # Link creation if 'link_id' in message_json: LOGGER.debug('Link creation') link = Link(**message_json) service = Service() Loading @@ -114,12 +114,12 @@ class SubscriptionServer(Thread): service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED service_client.CreateService(service) links = context_client.ListLinks(Empty()).links a_device_uuid = device_get_uuid(link.link_endpoint_ids[0].device_id) a_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[0])[2] z_device_uuid = device_get_uuid(link.link_endpoint_ids[1].device_id) z_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[1])[2] links = context_client.ListLinks(Empty()).links for _link in links: for _endpoint_id in _link.link_endpoint_ids: if _endpoint_id.device_id.device_uuid.uuid == a_device_uuid and \ Loading @@ -130,7 +130,9 @@ class SubscriptionServer(Thread): z_ep_id = _endpoint_id if (not 'a_ep_id' in locals()) or (not 'z_ep_id' in locals()): error_msg = 'Could not get VNT link endpoints' error_msg = f'Could not get VNT link endpoints\ \n\ta_endpoint_uuid= {a_endpoint_uuid}\ \n\tz_endpoint_uuid= {z_device_uuid}' LOGGER.error(error_msg) connection.send(error_msg) return Loading @@ -138,20 +140,22 @@ class SubscriptionServer(Thread): service.service_endpoint_ids.append(copy.deepcopy(a_ep_id)) service.service_endpoint_ids.append(copy.deepcopy(z_ep_id)) # service_client.UpdateService(service) service_client.UpdateService(service) re_svc = context_client.GetService(service.service_id) connection.send(grpc_message_to_json_string(link)) # Link removal context_client.SetLink(link) elif 'link_uuid' in message_json: LOGGER.debug('Link removal') link_id = LinkId(**message_json) service_id = ServiceId() service_id.service_uuid.uuid = link_id.link_uuid.uuid service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME # service_client.DeleteService(service_id) service_client.DeleteService(service_id) connection.send(grpc_message_to_json_string(link_id)) context_client.RemoveLink(link_id) # Topology received else: LOGGER.debug('Topology received') topology_details = TopologyDetails(**message_json) context = Context() Loading Loading @@ -187,12 +191,12 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): i = 1 while True: try: LOGGER.info(f'Retrieving external controller #{i}') ADD = str(get_setting(f'EXT_CONTROLLER{i}_ADD')) PORT = str(get_setting(f'EXT_CONTROLLER{i}_PORT')) except Exception as e: break try: LOGGER.info(f'Retrieving external controller #{i}') url = f'http://{ADD}:{PORT}/tfs-api/context/{DEFAULT_CONTEXT_NAME}/topology_details/{DEFAULT_TOPOLOGY_NAME}' topo = requests.get(url).json() except Exception as e: Loading src/e2e_orchestrator/service/__main__.py +4 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,10 @@ from common.Settings import (ENVVAR_SUFIX_SERVICE_HOST, from .E2EOrchestratorService import E2EOrchestratorService terminate = threading.Event() LOGGER = None LOG_LEVEL = get_log_level() logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") LOGGER = logging.getLogger(__name__) def signal_handler(signal, frame): # pylint: disable=redefined-outer-name Loading @@ -37,12 +40,6 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name def main(): global LOGGER # pylint: disable=global-statement log_level = get_log_level() logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) Loading Loading
src/context/service/database/Link.py +5 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ from .models.TopologyModel import TopologyLinkModel, TopologyModel from .uuids.EndPoint import endpoint_get_uuid from .uuids.Link import link_get_uuid from .Events import notify_event_context, notify_event_link, notify_event_topology from .models.enums.LinkType import grpc_to_enum__link_type_enum LOGGER = logging.getLogger(__name__) Loading Loading @@ -67,8 +68,8 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link) raw_link_name = request.name link_name = raw_link_uuid if len(raw_link_name) == 0 else raw_link_name link_uuid = link_get_uuid(request.link_id, link_name=link_name, allow_random=True) now = datetime.datetime.utcnow() link_type = grpc_to_enum__link_type_enum(request.link_type) now = datetime.datetime.now(datetime.timezone.utc) topology_uuids : Set[str] = set() related_topologies : List[Dict] = list() Loading Loading @@ -117,6 +118,7 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link) link_data = [{ 'link_uuid' : link_uuid, 'link_name' : link_name, 'link_type' : link_type, 'total_capacity_gbps' : total_capacity_gbps, 'used_capacity_gbps' : used_capacity_gbps, 'created_at' : now, Loading @@ -129,6 +131,7 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link) index_elements=[LinkModel.link_uuid], set_=dict( link_name = stmt.excluded.link_name, link_type = stmt.excluded.link_type, total_capacity_gbps = stmt.excluded.total_capacity_gbps, used_capacity_gbps = stmt.excluded.used_capacity_gbps, updated_at = stmt.excluded.updated_at, Loading
src/context/service/database/models/LinkModel.py +7 −1 Original line number Diff line number Diff line Loading @@ -13,17 +13,20 @@ # limitations under the License. import operator from sqlalchemy import CheckConstraint, Column, DateTime, Float, ForeignKey, Integer, String from sqlalchemy import CheckConstraint, Column, DateTime, Enum, Float, ForeignKey, Integer, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from typing import Dict from ._Base import _Base from common.proto.context_pb2 import LinkTypeEnum from .enums.LinkType import ORM_LinkTypeEnum class LinkModel(_Base): __tablename__ = 'link' link_uuid = Column(UUID(as_uuid=False), primary_key=True) link_name = Column(String, nullable=False) link_type = Column(Enum(ORM_LinkTypeEnum), nullable=False) total_capacity_gbps = Column(Float, nullable=True) used_capacity_gbps = Column(Float, nullable=True) created_at = Column(DateTime, nullable=False) Loading @@ -44,11 +47,14 @@ class LinkModel(_Base): result = { 'link_id' : self.dump_id(), 'name' : self.link_name, 'link_type' : self.link_type.value, 'link_endpoint_ids': [ link_endpoint.endpoint.dump_id() for link_endpoint in sorted(self.link_endpoints, key=operator.attrgetter('position')) ], } if self.link_type is None: self.link_type = LinkTypeEnum.LINKTYPE_UNKNOWN if self.total_capacity_gbps is not None: attributes : Dict = result.setdefault('attributes', dict()) attributes.setdefault('total_capacity_gbps', self.total_capacity_gbps) Loading
src/context/service/database/models/enums/LinkType.py 0 → 100644 +32 −0 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (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. import enum, functools from common.proto.context_pb2 import LinkTypeEnum from ._GrpcToEnum import grpc_to_enum # IMPORTANT: Entries of enum class ORM_DeviceDriverEnum should be named as in # the proto files removing the prefixes. For example, proto item # DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG should be included as # OPENCONFIG. If item name does not match, automatic mapping of # proto enums to database enums will fail. class ORM_LinkTypeEnum(enum.Enum): UNKNOWN = LinkTypeEnum.LINKTYPE_UNKNOWN COPPER = LinkTypeEnum.LINKTYPE_COPPER VIRTUAL_COPPER = LinkTypeEnum.LINKTYPE_VIRTUAL_COPPER OPTICAL = LinkTypeEnum.LINKTYPE_OPTICAL VIRTUAL_OPTICAL = LinkTypeEnum.LINKTYPE_VIRTUAL_OPTICAL grpc_to_enum__link_type_enum = functools.partial( grpc_to_enum, LinkTypeEnum, ORM_LinkTypeEnum)
src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +13 −9 Original line number Diff line number Diff line Loading @@ -80,7 +80,6 @@ class SubscriptionServer(Thread): LOGGER.debug("Received message from WebSocket: {}".format(message)) except Exception as ex: LOGGER.error('Exception receiving from WebSocket: {}'.format(ex)) self._events_server() Loading @@ -99,12 +98,13 @@ class SubscriptionServer(Thread): def _event_received(self, connection): LOGGER.debug('Event received') for message in connection: message_json = json.loads(message) # LOGGER.info("message_json: {}".format(message_json)) # Link creation if 'link_id' in message_json: LOGGER.debug('Link creation') link = Link(**message_json) service = Service() Loading @@ -114,12 +114,12 @@ class SubscriptionServer(Thread): service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED service_client.CreateService(service) links = context_client.ListLinks(Empty()).links a_device_uuid = device_get_uuid(link.link_endpoint_ids[0].device_id) a_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[0])[2] z_device_uuid = device_get_uuid(link.link_endpoint_ids[1].device_id) z_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[1])[2] links = context_client.ListLinks(Empty()).links for _link in links: for _endpoint_id in _link.link_endpoint_ids: if _endpoint_id.device_id.device_uuid.uuid == a_device_uuid and \ Loading @@ -130,7 +130,9 @@ class SubscriptionServer(Thread): z_ep_id = _endpoint_id if (not 'a_ep_id' in locals()) or (not 'z_ep_id' in locals()): error_msg = 'Could not get VNT link endpoints' error_msg = f'Could not get VNT link endpoints\ \n\ta_endpoint_uuid= {a_endpoint_uuid}\ \n\tz_endpoint_uuid= {z_device_uuid}' LOGGER.error(error_msg) connection.send(error_msg) return Loading @@ -138,20 +140,22 @@ class SubscriptionServer(Thread): service.service_endpoint_ids.append(copy.deepcopy(a_ep_id)) service.service_endpoint_ids.append(copy.deepcopy(z_ep_id)) # service_client.UpdateService(service) service_client.UpdateService(service) re_svc = context_client.GetService(service.service_id) connection.send(grpc_message_to_json_string(link)) # Link removal context_client.SetLink(link) elif 'link_uuid' in message_json: LOGGER.debug('Link removal') link_id = LinkId(**message_json) service_id = ServiceId() service_id.service_uuid.uuid = link_id.link_uuid.uuid service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME # service_client.DeleteService(service_id) service_client.DeleteService(service_id) connection.send(grpc_message_to_json_string(link_id)) context_client.RemoveLink(link_id) # Topology received else: LOGGER.debug('Topology received') topology_details = TopologyDetails(**message_json) context = Context() Loading Loading @@ -187,12 +191,12 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): i = 1 while True: try: LOGGER.info(f'Retrieving external controller #{i}') ADD = str(get_setting(f'EXT_CONTROLLER{i}_ADD')) PORT = str(get_setting(f'EXT_CONTROLLER{i}_PORT')) except Exception as e: break try: LOGGER.info(f'Retrieving external controller #{i}') url = f'http://{ADD}:{PORT}/tfs-api/context/{DEFAULT_CONTEXT_NAME}/topology_details/{DEFAULT_TOPOLOGY_NAME}' topo = requests.get(url).json() except Exception as e: Loading
src/e2e_orchestrator/service/__main__.py +4 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,10 @@ from common.Settings import (ENVVAR_SUFIX_SERVICE_HOST, from .E2EOrchestratorService import E2EOrchestratorService terminate = threading.Event() LOGGER = None LOG_LEVEL = get_log_level() logging.basicConfig(level=LOG_LEVEL, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s") LOGGER = logging.getLogger(__name__) def signal_handler(signal, frame): # pylint: disable=redefined-outer-name Loading @@ -37,12 +40,6 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name def main(): global LOGGER # pylint: disable=global-statement log_level = get_log_level() logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) Loading