Commit 19b287d6 authored by Waleed Akbar's avatar Waleed Akbar
Browse files

feat: Update SIMAP Connector Service and related components

- Added support for connection management in the SIMAP Connector Service.
- Updated connection environment variables in simap_connectorservice.yaml.
- Enhanced Connection.py with a new function to retrieve connections.
- Modified SimapConnectorServiceServicerImpl.py to assert worker types.
- Refactored __main__.py for improved import organization.
- Updated ObjectCache.py to handle connection objects and caching logic.
- Enhanced SimapUpdater.py with connection event handling and telemetry updates.
- Added utility functions in Tools.py for connection endpoint and link retrieval.
- Improved worker class in _Worker.py for better thread management.
- Updated SyntheticSamplers.py to use current timestamp for sampling.
- Added new JSON test data for L3VPN requests.
- Created deployment and dummy scripts for L3VPN testing.
- Added log dumping script for easier log collection during testing.
parent 3e7bde97
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ venv.bak/

# VSCode project settings
.vscode/
.github/

# Visual Studio project settings
/.vs
+2 −8
Original line number Diff line number Diff line
@@ -40,15 +40,9 @@ spec:
            - name: SIMAP_SERVER_SCHEME
              value: "http"
            - name: SIMAP_SERVER_ADDRESS
              # Assuming SIMAP Server is deployed in a local Docker container, as per:
              # - ./src/tests/tools/simap_server/build.sh
              # - ./src/tests/tools/simap_server/deploy.sh
              value: "172.17.0.1"
              value: "10.254.0.9" # running at SIMAP Server VM
            - name: SIMAP_SERVER_PORT
              # Assuming SIMAP Server is deployed in a local Docker container, as per:
              # - ./src/tests/tools/simap_server/build.sh
              # - ./src/tests/tools/simap_server/deploy.sh
              value: "8080"
              value: "8080"   # running at SIMAP Server VM
            - name: SIMAP_SERVER_USERNAME
              value: "admin"
            - name: SIMAP_SERVER_PASSWORD
+11 −2
Original line number Diff line number Diff line
@@ -13,8 +13,9 @@
# limitations under the License.

import grpc, logging
from typing import Optional
from common.proto.context_pb2 import Connection, ConnectionId
from typing import List, Optional
from common.Constants import DEFAULT_CONTEXT_NAME
from common.proto.context_pb2 import Connection, ConnectionId, ContextId
from context.client.ContextClient import ContextClient

LOGGER = logging.getLogger(__name__)
@@ -41,3 +42,11 @@ def get_connection_by_uuid(
    connection_id = ConnectionId()
    connection_id.connection_uuid.uuid = connection_uuid
    return get_connection_by_id(context_client, connection_id, rw_copy=rw_copy)

def get_connections(
    context_client : ContextClient, context_uuid : str = DEFAULT_CONTEXT_NAME
) -> List[Connection]:
    context_id = ContextId()
    context_id.context_uuid.uuid = context_uuid
    connections = context_client.ListConnections(context_id)
    return [c for c in connections.connections]
+5 −3
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ from common.tools.rest_conf.client.RestConfClient import RestConfClient
from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
from device.client.DeviceClient import DeviceClient
from simap_connector.service.telemetry.worker.SynthesizerWorker import SynthesizerWorker
from simap_connector.service.telemetry.worker._Worker import WorkerTypeEnum
from simap_connector.service.telemetry.worker._Worker import _Worker, WorkerTypeEnum
from .database.Subscription import subscription_get, subscription_set, subscription_delete
from .database.SubSubscription import (
    sub_subscription_list, sub_subscription_set, sub_subscription_delete
@@ -167,11 +167,13 @@ class SimapConnectorServiceServicerImpl(SimapConnectorServiceServicer):
        latency_factor   = request.latency_factor

        synthesizer_name = '{:s}:{:s}'.format(network_id, link_id)
        synthesizer : Optional[SynthesizerWorker] = self._telemetry_pool.get_worker(
        synthesizer : Optional[_Worker] = self._telemetry_pool.get_worker(
                        WorkerTypeEnum.SYNTHESIZER, synthesizer_name
        )
        if synthesizer is None:
            MSG = 'Synthesizer({:s}) not found'
            raise Exception(MSG.format(synthesizer_name))
        assert isinstance(synthesizer, SynthesizerWorker), \
            'Expected SynthesizerWorker, got {:s}'.format(type(synthesizer).__name__)
        synthesizer.change_resources(bandwidth_factor, latency_factor)
        return Empty()
+23 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ from common.tools.context_queries.Device import get_device, get_devices
from common.tools.context_queries.Link       import get_link, get_links
from common.tools.context_queries.Topology   import get_topology, get_topologies
from common.tools.context_queries.Service    import get_service_by_uuid, get_services
from common.tools.context_queries.Connection import get_connection_by_uuid, get_connections
from context.client.ContextClient import ContextClient


@@ -41,7 +42,7 @@ KEY_LENGTHS = {
    CachedEntities.ENDPOINT   : 2,
    CachedEntities.LINK       : 1,
    CachedEntities.SERVICE    : 1,
    CachedEntities.CONNECTION : 3,
    CachedEntities.CONNECTION : 1,
}


@@ -113,6 +114,10 @@ class ObjectCache:
            object_inst = get_service_by_uuid(
                self._context_client, object_uuids[0], rw_copy=False
            )
        elif entity == CachedEntities.CONNECTION:
            object_inst = get_connection_by_uuid(
                self._context_client, object_uuids[0], rw_copy=False
            )
        else:
            MSG = 'Not Supported ({:s}, {:s})'
            LOGGER.warning(MSG.format(str(entity.value).title(), str(object_uuids)))
@@ -124,6 +129,8 @@ class ObjectCache:
            return None

        self.set(entity, object_inst, object_uuids[0])
        # Connections don't have a name field, so skip setting by name
        if entity != CachedEntities.CONNECTION:
            self.set(entity, object_inst, object_inst.name)

        if entity == CachedEntities.DEVICE:
@@ -173,6 +180,12 @@ class ObjectCache:
                (s.service_id.service_uuid.uuid, s.name) : s
                for s in objects
            }
        elif entity == CachedEntities.CONNECTION:
            objects = get_connections(self._context_client)
            objects = {
                (c.connection_id.connection_uuid.uuid, c.connection_id.connection_uuid.uuid) : c
                for c in objects
            }
        else:
            MSG = 'Not Supported ({:s})'
            LOGGER.warning(MSG.format(str(entity.value).title()))
@@ -180,6 +193,8 @@ class ObjectCache:

        for (object_uuid, object_name), object_inst in objects.items():
            self.set(entity, object_inst, object_uuid)
            # Connections don't have a name field (object_name is same as UUID), so skip redundant set
            if entity != CachedEntities.CONNECTION:
                self.set(entity, object_inst, object_name)

            if entity == CachedEntities.DEVICE:
Loading