Commit 07fbb684 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'feat/402-cttc-add-nbi-tfs-api-endpoints-to-manage-optical-links' into 'develop'

Resolve "(CTTC) Add NBI TFS-API endpoints to manage optical links"

See merge request !465
parents 89a09e01 b7b386c0
Loading
Loading
Loading
Loading
+30 −8
Original line number Diff line number Diff line
@@ -135,8 +135,12 @@ class MockServicerImpl_Context(ContextServiceServicer):
        reply.topology_id.CopyFrom(_reply.topology_id) # pylint: disable=no-member
        reply.name = _reply.name
        if context_uuid == DEFAULT_CONTEXT_NAME and topology_uuid == DEFAULT_TOPOLOGY_NAME:
            for device in self.obj_db.get_entries('device'): reply.devices.append(device)   # pylint: disable=no-member
            for link   in self.obj_db.get_entries('link'  ): reply.links  .append(link  )   # pylint: disable=no-member
            for device in self.obj_db.get_entries('device'):
                reply.devices.append(device)                # pylint: disable=no-member
            for link in self.obj_db.get_entries('link'):
                reply.links.append(link)                    # pylint: disable=no-member
            for optical_link in self.obj_db.get_entries('optical_link'):
                reply.optical_links.append(optical_link)    # pylint: disable=no-member
        else:
            # TODO: to be improved; Mock does not associate devices/links to topologies automatically
            for device_id in _reply.device_ids:
@@ -145,6 +149,9 @@ class MockServicerImpl_Context(ContextServiceServicer):
            for link_id in _reply.link_ids:
                link = self.obj_db.get_entry('link', link_id.link_uuid.uuid, context)
                reply.links.append(link)                    # pylint: disable=no-member
            for optical_link_id in _reply.optical_link_ids:
                optical_link = self.obj_db.get_entry('optical_link', optical_link_id.link_uuid.uuid, context)
                reply.optical_links.append(optical_link)    # pylint: disable=no-member
        LOGGER.debug('[GetTopologyDetails] reply={:s}'.format(grpc_message_to_json_string(reply)))
        return reply

@@ -159,12 +166,22 @@ class MockServicerImpl_Context(ContextServiceServicer):
            db_topology = self.obj_db.get_entry(container_name, topology_uuid, context)

            device_uuids = set()
            for device_id in request.device_ids: device_uuids.add(device_id.device_uuid.uuid)
            for device_id in db_topology.device_ids: device_uuids.add(device_id.device_uuid.uuid)
            for device_id in request.device_ids:
                device_uuids.add(device_id.device_uuid.uuid)
            for device_id in db_topology.device_ids:
                device_uuids.add(device_id.device_uuid.uuid)

            link_uuids = set()
            for link_id in request.link_ids: link_uuids.add(link_id.link_uuid.uuid)
            for link_id in db_topology.link_ids: link_uuids.add(link_id.link_uuid.uuid)
            for link_id in request.link_ids:
                link_uuids.add(link_id.link_uuid.uuid)
            for link_id in db_topology.link_ids:
                link_uuids.add(link_id.link_uuid.uuid)

            optical_link_uuids = set()
            for optical_link_id in request.optical_link_ids:
                optical_link_uuids.add(optical_link_id.link_uuid.uuid)
            for optical_link_id in db_topology.optical_link_ids:
                optical_link_uuids.add(optical_link_id.link_uuid.uuid)

            rw_request = Topology()
            rw_request.CopyFrom(request)
@@ -179,6 +196,11 @@ class MockServicerImpl_Context(ContextServiceServicer):
            for link_uuid in sorted(link_uuids):
                rw_request.link_ids.append(LinkId(**json_link_id(link_uuid)))

            # pylint: disable=no-member
            del rw_request.optical_link_ids[:]
            for optical_link_uuid in sorted(optical_link_uuids):
                rw_request.optical_link_ids.append(LinkId(**json_link_id(optical_link_uuid)))

            request = rw_request

        reply,_ = self._set(request, container_name, topology_uuid, 'topology_id', TOPIC_TOPOLOGY)
+50 −2
Original line number Diff line number Diff line
@@ -465,7 +465,7 @@ def validate_slice(message):
        assert 'owner_string' in message['slice_owner']
        assert isinstance(message['slice_owner']['owner_string'], str)

def validate_topology(message, num_devices=None, num_links=None):
def validate_topology(message, num_devices=None, num_links=None, num_optical_links=None):
    assert isinstance(message, dict)
    assert len(message.keys()) == 5
    assert 'topology_id' in message
@@ -482,7 +482,7 @@ def validate_topology(message, num_devices=None, num_links=None):
    for link_id in message['link_ids']: validate_link_id(link_id)
    assert 'optical_link_ids' in message
    assert isinstance(message['optical_link_ids'], list)
    #if num_links is not None: assert len(message['optical_link_ids']) == num_links
    if num_optical_links is not None: assert len(message['optical_link_ids']) == num_optical_links
    for link_id in message['optical_link_ids']: validate_link_id(link_id)

def validate_endpoint(message):
@@ -575,6 +575,47 @@ def validate_link(message):
    assert 'link_type' in message
    validate_link_type_enum(message['link_type'])

def validate_optical_slot_map(message):
    assert isinstance(message, dict)
    for key, value in message.items():
        assert isinstance(key, str)
        assert isinstance(value, int)

def validate_optical_link_details(message):
    assert isinstance(message, dict)
    assert len(message.keys()) == 9
    assert 'length' in message
    assert isinstance(message['length'], (int, float))
    assert 'src_port' in message
    assert isinstance(message['src_port'], str)
    assert 'dst_port' in message
    assert isinstance(message['dst_port'], str)
    assert 'local_peer_port' in message
    assert isinstance(message['local_peer_port'], str)
    assert 'remote_peer_port' in message
    assert isinstance(message['remote_peer_port'], str)
    assert 'used' in message
    assert isinstance(message['used'], bool)
    assert 'c_slots' in message
    validate_optical_slot_map(message['c_slots'])
    assert 'l_slots' in message
    validate_optical_slot_map(message['l_slots'])
    assert 's_slots' in message
    validate_optical_slot_map(message['s_slots'])

def validate_optical_link(message):
    assert isinstance(message, dict)
    assert len(message.keys()) == 4
    assert 'link_id' in message
    validate_link_id(message['link_id'])
    assert 'name' in message
    assert isinstance(message['name'], str)
    assert 'link_endpoint_ids' in message
    assert isinstance(message['link_endpoint_ids'], list)
    for endpoint_id in message['link_endpoint_ids']: validate_endpoint_id(endpoint_id)
    assert 'optical_details' in message
    validate_optical_link_details(message['optical_details'])

def validate_connection(message):
    assert isinstance(message, dict)
    assert len(message.keys()) in {4, 5}
@@ -678,6 +719,13 @@ def validate_links(message):
    assert isinstance(message['links'], list)
    for link in message['links']: validate_link(link)

def validate_optical_links(message):
    assert isinstance(message, dict)
    assert len(message.keys()) == 1
    assert 'optical_links' in message
    assert isinstance(message['optical_links'], list)
    for optical_link in message['optical_links']: validate_optical_link(optical_link)

def validate_connections(message):
    assert isinstance(message, dict)
    assert len(message.keys()) == 1
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ def topology_list_objs(db_engine : Engine, request : ContextId) -> TopologyList:
        obj_list : List[TopologyModel] = session.query(TopologyModel)\
            .options(selectinload(TopologyModel.topology_devices))\
            .options(selectinload(TopologyModel.topology_links))\
            .options(selectinload(TopologyModel.topology_optical_links))\
            .filter_by(context_uuid=context_uuid).all()
        return [obj.dump() for obj in obj_list]
    topologies = run_transaction(sessionmaker(bind=db_engine), callback)
@@ -62,6 +63,7 @@ def topology_get(db_engine : Engine, request : TopologyId) -> Topology:
        obj : Optional[TopologyModel] = session.query(TopologyModel)\
            .options(selectinload(TopologyModel.topology_devices))\
            .options(selectinload(TopologyModel.topology_links))\
            .options(selectinload(TopologyModel.topology_optical_links))\
            .filter_by(topology_uuid=topology_uuid).one_or_none()
        return None if obj is None else obj.dump()
    obj = run_transaction(sessionmaker(bind=db_engine), callback)
+8 −0
Original line number Diff line number Diff line
@@ -337,6 +337,14 @@ class Link(_Resource):
        else:
            return format_grpc_to_json(self.context_client.RemoveLink(link_id))

class OpticalLinks(_Resource):
    def get(self):
        return format_grpc_to_json(self.context_client.GetOpticalLinkList(Empty()))

class OpticalLink(_Resource):
    def get(self, link_uuid : str):
        return format_grpc_to_json(self.context_client.GetOpticalLink(grpc_link_id(link_uuid)))

class ConnectionIds(_Resource):
    def get(self, context_uuid : str, service_uuid : str):
        return format_grpc_to_json(self.context_client.ListConnectionIds(grpc_service_id(context_uuid, service_uuid)))
+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ from .Resources import (
    Device, DeviceIds, Devices,
    DummyContexts,
    Link, LinkIds, Links,
    OpticalLink, OpticalLinks,
    PolicyRule, PolicyRuleIds, PolicyRules,
    Service, ServiceIds, Services,
    Slice, SliceIds, Slices,
@@ -56,6 +57,8 @@ _RESOURCES = [
    ('api.link_ids',         LinkIds,         '/link_ids'),
    ('api.links',            Links,           '/links'),
    ('api.link',             Link,            '/link/<path:link_uuid>'),
    ('api.optical_links',    OpticalLinks,    '/optical_links'),
    ('api.optical_link',     OpticalLink,     '/optical_link/<path:link_uuid>'),

    ('api.connection_ids',   ConnectionIds,   '/context/<path:context_uuid>/service/<path:service_uuid>/connection_ids'),
    ('api.connections',      Connections,     '/context/<path:context_uuid>/service/<path:service_uuid>/connections'),
Loading