diff --git a/src/service/service/path_computation_element/Enums.py b/src/service/service/path_computation_element/Enums.py
deleted file mode 100644
index f55d545b54abf1749e1757200b509562dd4d0455..0000000000000000000000000000000000000000
--- a/src/service/service/path_computation_element/Enums.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# 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.
-
-from enum import Enum
-
-class NodeTypeEnum(Enum):
-    DEVICE   = 'device'
-    ENDPOINT = 'endpoint'
-
-class EndPointTypeEnum(Enum):
-    COPPER    = 'copper'
-    OPTICAL   = 'optical'
-    MICROWAVE = 'microwave'
-
-class EdgeTypeEnum(Enum):
-    INTERNAL  = 'internal'
-    COPPER    = 'copper'
-    OPTICAL   = 'optical'
-    MICROWAVE = 'microwave'
-    VIRTUAL   = 'virtual'
-    OTHER     = 'other'
-
-class LayerTypeEnum(Enum):
-    COPPER    = 'copper'
-    OPTICAL   = 'optical'
-    MICROWAVE = 'microwave'
diff --git a/src/service/service/path_computation_element/PathComputationElement.py b/src/service/service/path_computation_element/PathComputationElement.py
deleted file mode 100644
index 80316ac8965ebdbed99264127465488a946f6782..0000000000000000000000000000000000000000
--- a/src/service/service/path_computation_element/PathComputationElement.py
+++ /dev/null
@@ -1,373 +0,0 @@
-# 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.
-
-import grpc, json, logging, networkx, uuid
-from queue import Queue
-from typing import Dict, List, Tuple
-from networkx.drawing.nx_pydot import write_dot
-from common.Constants import DEFAULT_CONTEXT_UUID
-from common.DeviceTypes import DeviceTypeEnum
-from common.proto.context_pb2 import (
-    ConfigActionEnum, Connection, Device, Empty, EndPoint, EndPointId, Service, ServiceId, ServiceStatusEnum,
-    ServiceTypeEnum)
-from common.tools.grpc.Tools import (
-    grpc_message_list_to_json, grpc_message_list_to_json_string, grpc_message_to_json, grpc_message_to_json_string)
-from context.client.ContextClient import ContextClient
-from .Enums import EdgeTypeEnum, NodeTypeEnum
-from .Tools import get_device, get_device_key, get_edge_type, get_endpoint, get_endpoint_key, get_link_key
-
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.INFO)
-
-SUB_SERVICE_TYPES = {
-    DeviceTypeEnum.EMULATED_PACKET_ROUTER.value   : ServiceTypeEnum.SERVICETYPE_L3NM,
-    DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value: ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
-    DeviceTypeEnum.PACKET_ROUTER.value            : ServiceTypeEnum.SERVICETYPE_L3NM,
-    DeviceTypeEnum.OPEN_LINE_SYSTEM.value         : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
-}
-DEFAULT_SUB_SERVICE_TYPE = ServiceTypeEnum.SERVICETYPE_UNKNOWN
-
-def dump_requirements(requirements):
-    if requirements is None: return None
-    return [
-        {
-            'sub_service': grpc_message_to_json(sub_service),
-            'sub_connections': grpc_message_list_to_json(sub_connections),
-        }
-        for sub_service,sub_connections in requirements
-    ]
-
-def dump_connectivity(connectivity):
-    if connectivity is None: return None
-    return {
-        'service': grpc_message_to_json(connectivity.get('service')),
-        'connections': grpc_message_list_to_json(connectivity.get('connections', [])),
-        'requirements': dump_requirements(connectivity.get('requirements', [])),
-    }
-
-def dump_hops(hops):
-    if hops is None: return None
-    return [
-        'in_endpoint={:s}, device={:s}, out_endpoint={:s}'.format(
-            grpc_message_to_json_string(in_endpoint), grpc_message_to_json_string(device),
-            grpc_message_to_json_string(out_endpoint))
-        for in_endpoint,device,out_endpoint in hops
-    ]
-
-class PathComputationElement:
-    def __init__(self) -> None:
-        self.__topology = networkx.Graph()
-        self.__connectivity = {} # (a_ep_key, z_ep_key) => {service, connection, sub_services: [], sub_connections: []}
-        self.__service_endpoints = {} # (context_uuid, service_uuid) => (a_ep_key, z_ep_key)
-
-    def dump_topology_to_file(self, dot_filepath : str):
-        write_dot(self.__topology, dot_filepath)
-
-    def dump_connectivity_to_file(self, filepath : str):
-        with open(filepath, 'w', encoding='UTF-8') as f:
-            f.write(str(self.__connectivity)) # do not use json; it contains protobuf objects
-
-    def load_topology(self, context_client : ContextClient):
-        response_devices = context_client.ListDevices(Empty())
-        devices = response_devices.devices
-        LOGGER.debug('Devices[{:d}] = {:s}'.format(len(devices), grpc_message_to_json_string(response_devices)))
-        assert len(devices) > 0
-
-        response_links = context_client.ListLinks(Empty())
-        links = response_links.links
-        LOGGER.debug('Links[{:d}] = {:s}'.format(len(links), grpc_message_to_json_string(response_links)))
-        assert len(links) > 0
-
-        for device in response_devices.devices:
-            device_uuid = get_device_key(device.device_id)
-            self.__topology.add_node(device_uuid, node_type=NodeTypeEnum.DEVICE, device=device)
-            for endpoint in device.device_endpoints:
-                endpoint_key = get_endpoint_key(endpoint.endpoint_id, device_uuid=device_uuid)
-                self.__topology.add_node(endpoint_key, node_type=NodeTypeEnum.ENDPOINT, endpoint=endpoint)
-                self.__topology.add_edge(device_uuid, endpoint_key, edge_type=EdgeTypeEnum.INTERNAL)
-
-        for link in response_links.links:
-            link_uuid = get_link_key(link.link_id)
-            if len(link.link_endpoint_ids) != 2:
-                msg = 'Link({:s}) with {:d} != 2 endpoints'
-                raise NotImplementedError(msg.format(link_uuid, len(link.link_endpoint_ids)))
-            endpoint_keys = [get_endpoint_key(endpoint_id) for endpoint_id in link.link_endpoint_ids]
-            edge_type = get_edge_type(self.__topology, endpoint_keys)
-            self.__topology.add_edge(endpoint_keys[0], endpoint_keys[1], link=link, edge_type=edge_type)
-
-    def load_connectivity(self, context_client : ContextClient, service_id : ServiceId):
-        pending_service_ids = Queue()
-        pending_service_ids.put((service_id, True))
-
-        connectivity = {}
-        requirements : List[Tuple[Service, List[Connection]]] = connectivity.setdefault('requirements', [])
-        connections : List[Connection] = connectivity.setdefault('connections', [])
-
-        while not pending_service_ids.empty():
-            service_id,is_main = pending_service_ids.get()
-
-            try:
-                service = context_client.GetService(service_id)
-                LOGGER.debug('[load_connectivity] GetService({:s}) = {:s}'.format(
-                    grpc_message_to_json_string(service_id), grpc_message_to_json_string(service)))
-            except grpc.RpcError as e:
-                if is_main and e.code() == grpc.StatusCode.NOT_FOUND: continue # pylint: disable=no-member
-                raise
-
-            # TODO: implement support for services with more than 2 endpoints;
-            # Right now, services with less than 2 endpoints are ignored; with more than 2 endpoints throws exception.
-            # e.g., compute pairs such as:
-            #   list(filter(lambda ep: ep[0] < ep[1], itertools.product(service_endpoint_ids, service_endpoint_ids)))
-            service_endpoint_ids = service.service_endpoint_ids
-            if len(service_endpoint_ids) < 2: continue
-            if len(service_endpoint_ids) > 2: raise NotImplementedError('Service with more than 2 endpoints')
-
-            service_connections = context_client.ListConnections(service_id)
-            LOGGER.debug('[load_connectivity] ListConnections({:s}) = {:s}'.format(
-                grpc_message_to_json_string(service_id), grpc_message_to_json_string(service_connections)))
-
-            if is_main:
-                connectivity['service'] = service
-                a_endpoint_key = get_endpoint_key(service_endpoint_ids[0])
-                z_endpoint_key = get_endpoint_key(service_endpoint_ids[-1])
-                self.__connectivity[(a_endpoint_key, z_endpoint_key)] = connectivity
-                self.__connectivity[(z_endpoint_key, a_endpoint_key)] = connectivity
-                context_service_id = (service_id.context_id.context_uuid.uuid, service_id.service_uuid.uuid)
-                self.__service_endpoints[context_service_id] = (a_endpoint_key, z_endpoint_key)
-                connections.extend(service_connections.connections)
-            else:
-                requirements.append((service, service_connections.connections))
-
-            for connection in service_connections.connections:
-                for service_id in connection.sub_service_ids:
-                    pending_service_ids.put((service_id, False))
-
-    def get_connectivity_from_service_id(self, service_id : ServiceId) -> Dict:
-        LOGGER.debug('[get_connectivity_from_service_id] service_id={:s}'.format(
-            grpc_message_to_json_string(service_id)))
-
-        context_uuid = service_id.context_id.context_uuid.uuid
-        service_uuid = service_id.service_uuid.uuid
-        context_service_id = (context_uuid, service_uuid)
-        if context_service_id in self.__service_endpoints:
-            a_endpoint_key, z_endpoint_key = self.__service_endpoints[context_service_id]
-        else:
-            return None
-
-        if (a_endpoint_key, z_endpoint_key) in self.__connectivity:
-            connectivity = self.__connectivity.get((a_endpoint_key, z_endpoint_key))
-        elif (z_endpoint_key, a_endpoint_key) in self.__connectivity:
-            connectivity = self.__connectivity.get((z_endpoint_key, a_endpoint_key))
-        else:
-            connectivity = None
-
-        if connectivity is None or connectivity.get('connections') is None: return None
-        LOGGER.debug('[get_connectivity_from_service_id] Connectivity: {:s}'.format(
-            str(dump_connectivity(connectivity))))
-        return connectivity
-
-    def get_connectivity(self, service : Service) -> Tuple[Dict, str, str]:
-        LOGGER.debug('[get_connectivity] service.service_id = {:s}'.format(
-            grpc_message_to_json_string(service.service_id)))
-
-        context_uuid = service.service_id.context_id.context_uuid.uuid
-        service_uuid = service.service_id.service_uuid.uuid
-        context_service_id = (context_uuid, service_uuid)
-
-        if context_service_id in self.__service_endpoints:
-            LOGGER.debug('[get_connectivity] exists')
-            a_endpoint_key, z_endpoint_key = self.__service_endpoints[context_service_id]
-
-            LOGGER.debug('[get_connectivity] a_endpoint_key={:s}'.format(str(a_endpoint_key)))
-            LOGGER.debug('[get_connectivity] z_endpoint_key={:s}'.format(str(z_endpoint_key)))
-        else:
-            LOGGER.debug('[get_connectivity] new')
-            # TODO: implement support for services with more than 2 endpoints;
-            # Right now, less than 2 reports None, more than 2 endpoints throws an exception.
-            # e.g., compute pairs such as:
-            #   list(filter(lambda ep: ep[0] < ep[1], itertools.product(service_endpoint_ids, service_endpoint_ids)))
-            service_endpoint_ids = service.service_endpoint_ids
-
-            LOGGER.debug('[get_connectivity] service_endpoint_ids[{:d}] = {:s}'.format(
-                len(service_endpoint_ids), grpc_message_list_to_json_string(service_endpoint_ids)))
-
-            if len(service_endpoint_ids) < 2: return None
-            if len(service_endpoint_ids) > 2: raise NotImplementedError('Service with more than 2 endpoints')
-
-            a_endpoint_key = get_endpoint_key(service_endpoint_ids[0])
-            z_endpoint_key = get_endpoint_key(service_endpoint_ids[-1])
-            LOGGER.debug('[get_connectivity] a_endpoint_key={:s}'.format(str(a_endpoint_key)))
-            LOGGER.debug('[get_connectivity] z_endpoint_key={:s}'.format(str(z_endpoint_key)))
-
-        if (a_endpoint_key, z_endpoint_key) in self.__connectivity:
-            connectivity = self.__connectivity.get((a_endpoint_key, z_endpoint_key))
-        elif (z_endpoint_key, a_endpoint_key) in self.__connectivity:
-            connectivity = self.__connectivity.get((z_endpoint_key, a_endpoint_key))
-        else:
-            connectivity = None
-
-        LOGGER.debug('[get_connectivity] connectivity = {:s}'.format(str(dump_connectivity(connectivity))))
-
-        if connectivity is None or connectivity.get('connections') is None: return None, a_endpoint_key, z_endpoint_key
-        return connectivity, a_endpoint_key, z_endpoint_key
-
-    def route_service(self, service : Service):
-        if self.__topology is None: raise Exception('Topology has not been loaded')
-
-        connectivity = self.get_connectivity(service)
-        if connectivity is None:
-            LOGGER.debug('[route_service] connectivity = None')
-            return None
-        _, a_endpoint_key, z_endpoint_key = connectivity
-
-        LOGGER.debug('[route_service] a_endpoint_key={:s}'.format(str(a_endpoint_key)))
-        LOGGER.debug('[route_service] z_endpoint_key={:s}'.format(str(z_endpoint_key)))
-
-        # TODO: consider implementing something like a K-shortest path instead of a simple shortest path
-        # pylint: disable=no-value-for-parameter,unexpected-keyword-arg
-        #paths = networkx.all_shortest_paths(self.__topology, source=a_endpoint_key, target=z_endpoint_key)
-        path_node_keys = networkx.shortest_path(
-            self.__topology, source=a_endpoint_key, target=z_endpoint_key)
-        LOGGER.debug('[route_service] Path[{:d}] = {:s}'.format(len(path_node_keys), str(path_node_keys)))
-
-        if len(path_node_keys) % 3 != 0:
-            msg = 'Weird path: length({:d}) mod 3 != 0. Path should be a sequence of endpoint-device-endpoint, '\
-                  ' so it must be multiple of 3'
-            raise Exception(msg.format(len(path_node_keys)))
-
-        hops : List[Tuple[EndPoint, Device, EndPoint]] = []
-        device_type__to__hops : Dict[str, List[int]] = {}
-        for i in range(0, len(path_node_keys), 3):
-            hop_device = get_device(self.__topology, path_node_keys[i+1])
-            hop_a_endpoint = get_endpoint(self.__topology, path_node_keys[i+0])
-            hop_z_endpoint = get_endpoint(self.__topology, path_node_keys[i+2])
-
-            hop_device_key = get_device_key(hop_device.device_id)
-            hop_a_endpoint_device_key = get_device_key(hop_a_endpoint.endpoint_id.device_id)
-            hop_z_endpoint_device_key = get_device_key(hop_z_endpoint.endpoint_id.device_id)
-
-            if hop_a_endpoint_device_key != hop_device_key:
-                msg = 'Weird path: Hop[{:d}] a_endpoint.device({:s}) != device({:s})'
-                raise Exception(msg.format(i/3, str(hop_a_endpoint_device_key), str(hop_device_key)))
-            if hop_z_endpoint_device_key != hop_device_key:
-                msg = 'Weird path: Hop[{:d}] z_endpoint.device({:s}) != device({:s})'
-                raise Exception(msg.format(i/3, str(hop_z_endpoint_device_key), str(hop_device_key)))
-
-            hops.append((hop_a_endpoint, hop_device, hop_z_endpoint))
-            device_type__to__hops.setdefault(hop_device.device_type, []).append(len(hops) - 1)
-
-        LOGGER.debug('[route_service] hops[{:d}] = {:s}'.format(
-            len(hops), str(dump_hops(hops))))
-        LOGGER.debug('[route_service] device_type__to__hops = {:s}'.format(str(device_type__to__hops)))
-
-        context_uuid = service.service_id.context_id.context_uuid.uuid
-        service_uuid = service.service_id.service_uuid.uuid
-
-        # create main service's connection
-        main_service_device_type = hops[0][1].device_type
-        main_service_hop_indexes = device_type__to__hops.pop(main_service_device_type)
-
-        # create sub-service and sub-services' connections
-        sub_service_ids = []
-        requirements : List[Tuple[Service, List[Connection]]] = []
-        for sub_service_device_type, sub_service_hop_indexes in device_type__to__hops.items():
-            LOGGER.debug('[route_service] sub_service_device_type = {:s}'.format(str(sub_service_device_type)))
-            LOGGER.debug('[route_service] sub_service_hop_indexes = {:s}'.format(str(sub_service_hop_indexes)))
-
-            # create sub-service
-            sub_service_uuid = '{:s}:optical'.format(service_uuid)
-            sub_service_id = {
-                'context_id': {'context_uuid': {'uuid': context_uuid}},
-                'service_uuid': {'uuid': sub_service_uuid},
-            }
-            sub_service = Service(**{
-                'service_id': sub_service_id,
-                'service_type' : SUB_SERVICE_TYPES.get(sub_service_device_type, DEFAULT_SUB_SERVICE_TYPE),
-                'service_status': {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED},
-                'service_endpoint_ids': [
-                    hops[sub_service_hop_indexes[ 0]][ 0].endpoint_id,
-                    hops[sub_service_hop_indexes[-1]][-1].endpoint_id,
-                ],
-                'service_config': {'config_rules': [
-                    {
-                        'action': ConfigActionEnum.CONFIGACTION_SET,
-                        'custom': {
-                            'resource_key': 'settings',
-                            'resource_value': json.dumps({
-                                'capacity_value':   1,
-                                'capacity_unit':    'GHz',
-                                'layer_proto_name': 'PHOTONIC_MEDIA',
-                                'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC',
-                                'direction':        'UNIDIRECTIONAL',
-                            }, sort_keys=True),
-                        }
-                    }
-                ]},
-            })
-            LOGGER.debug('[route_service] sub_service = {:s}'.format(grpc_message_to_json_string(sub_service)))
-
-            # create sub-service's connection
-            sub_connection_uuid = '{:s}:{:s}'.format(sub_service_uuid, sub_service_device_type)
-            sub_conn_path_hops = []
-            for i in sub_service_hop_indexes:
-                sub_conn_path_hops.extend([hops[i][0].endpoint_id, hops[i][2].endpoint_id])
-            sub_connection = Connection(**{
-                'connection_id': {'connection_uuid': {'uuid': sub_connection_uuid}},
-                'service_id': sub_service_id,
-                'path_hops_endpoint_ids': sub_conn_path_hops,
-            })
-
-            LOGGER.debug('[route_service] sub_connection = {:s}'.format(grpc_message_to_json_string(sub_connection)))
-
-            sub_service_ids.append(sub_service_id)
-            requirements.append((sub_service, [sub_connection]))
-
-        LOGGER.debug('[route_service] sub_service_ids = {:s}'.format(str(sub_service_ids)))
-        LOGGER.debug('[route_service] requirements = {:s}'.format(str(dump_requirements(requirements))))
-        LOGGER.debug('[route_service] requirements[{:d}] = {:s}'.format(
-            len(requirements), str(dump_requirements(requirements))))
-
-        connections : List[Connection] = []
-
-        connection_uuid = '{:s}:{:s}'.format(service_uuid, main_service_device_type)
-        connection_path_hops : List[EndPointId] = []
-        for i in main_service_hop_indexes:
-            connection_path_hops.extend([hops[i][0].endpoint_id, hops[i][2].endpoint_id])
-        connection = Connection(**{
-            'connection_id': {'connection_uuid': {'uuid': connection_uuid}},
-            'service_id': grpc_message_to_json(service.service_id),
-            'path_hops_endpoint_ids': connection_path_hops,
-            'sub_service_ids': sub_service_ids,
-        })
-        LOGGER.debug('[route_service] connection = {:s}'.format(grpc_message_to_json_string(connection)))
-        connections.append(connection)
-            
-        LOGGER.debug('[route_service] connections[{:d}] = {:s}'.format(
-            len(connections), grpc_message_list_to_json_string(connections)))
-
-        connectivity = {
-            'service': service,
-            'connections': connections,
-            'requirements': requirements,
-        }
-
-        LOGGER.debug('[route_service] connectivity = {:s}'.format(str(dump_connectivity(connectivity))))
-
-        self.__connectivity[(a_endpoint_key, z_endpoint_key)] = connectivity
-        self.__connectivity[(z_endpoint_key, a_endpoint_key)] = connectivity
-
-        context_service_id = (context_uuid, service_uuid)
-        self.__service_endpoints[context_service_id] = (a_endpoint_key, z_endpoint_key)
-
-        return connectivity
diff --git a/src/service/service/path_computation_element/Tools.py b/src/service/service/path_computation_element/Tools.py
deleted file mode 100644
index d8ebdd36dcd5511bd1031a31cafa047d9e04fccf..0000000000000000000000000000000000000000
--- a/src/service/service/path_computation_element/Tools.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# 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.
-
-import networkx
-from typing import List, Optional
-from common.proto.context_pb2 import Device, DeviceId, EndPoint, EndPointId, LinkId
-from .Enums import EdgeTypeEnum
-
-def get_device_key(device_id : DeviceId) -> str:
-    return device_id.device_uuid.uuid # pylint: disable=no-member
-
-def get_endpoint_key(endpoint_id : EndPointId, device_uuid : Optional[str] = None) -> str:
-    if device_uuid is None: device_uuid = endpoint_id.device_id.device_uuid.uuid # pylint: disable=no-member
-    endpoint_uuid = endpoint_id.endpoint_uuid.uuid # pylint: disable=no-member
-    return '{:s}/{:s}'.format(device_uuid, endpoint_uuid)
-
-def get_link_key(link_id : LinkId) -> str:
-    return link_id.link_uuid.uuid # pylint: disable=no-member
-
-def get_device(topology : networkx.Graph, device_key : str) -> Device:
-    return topology.nodes[device_key]['device']
-
-def get_endpoint(topology : networkx.Graph, endpoint_key : str) -> EndPoint:
-    return topology.nodes[endpoint_key]['endpoint']
-
-def get_edge_type(topology : networkx.Graph, endpoint_keys : List[str]) -> EdgeTypeEnum:
-    # pylint: disable=no-member,protected-access
-    endpoint_types = {get_endpoint(topology, endpoint_key).endpoint_type for endpoint_key in endpoint_keys}
-    edge_type = None if len(endpoint_types) > 1 else \
-        EdgeTypeEnum._value2member_map_.get(endpoint_types.pop())
-    if edge_type is None: edge_type = EdgeTypeEnum.OTHER
-    return edge_type
diff --git a/src/service/service/path_computation_element/TopologyViews.py b/src/service/service/path_computation_element/TopologyViews.py
deleted file mode 100644
index e9161dc0d4e491d8fdfa239b8603fbf6613967ff..0000000000000000000000000000000000000000
--- a/src/service/service/path_computation_element/TopologyViews.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# 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.
-
-import functools, networkx
-from typing import List, Optional, Union
-from common.proto.context_pb2 import EndPoint
-from context.service.database.EndPointModel import EndPointModel
-from .Enums import EdgeTypeEnum, LayerTypeEnum
-#from .Tools import get_endpoint
-
-def select_copper_edges(topology, n1, n2):
-    selected_edges = {EdgeTypeEnum.COPPER, EdgeTypeEnum.INTERNAL, EdgeTypeEnum.OTHER}
-    return topology[n1][n2].get('edge_type', EdgeTypeEnum.OTHER) in selected_edges
-
-def select_optical_edges(topology, n1, n2):
-    selected_edges = {EdgeTypeEnum.OPTICAL, EdgeTypeEnum.INTERNAL, EdgeTypeEnum.OTHER}
-    return topology[n1][n2].get('edge_type', EdgeTypeEnum.OTHER) in selected_edges
-
-def select_microwave_edges(topology, n1, n2):
-    selected_edges = {EdgeTypeEnum.MICROWAVE, EdgeTypeEnum.INTERNAL, EdgeTypeEnum.OTHER}
-    return topology[n1][n2].get('edge_type', EdgeTypeEnum.OTHER) in selected_edges
-
-SELECT_LAYER = {
-    LayerTypeEnum.COPPER    : select_copper_edges,
-    LayerTypeEnum.OPTICAL   : select_optical_edges,
-    LayerTypeEnum.MICROWAVE : select_microwave_edges,
-}
-
-def get_layer(topology : networkx.Graph, layer : LayerTypeEnum):
-    filter_edge = functools.partial(SELECT_LAYER[layer], topology)
-    return networkx.subgraph_view(topology, filter_edge=filter_edge)
-
-def select_layer_from_endpoints(endpoints : List[Union[EndPointModel, EndPoint]]) -> Optional[LayerTypeEnum]:
-    endpoint_types = set()
-    for endpoint in endpoints: endpoint_types.add(endpoint.endpoint_type)
-    if len(endpoint_types) != 1: return None
-    # pylint: disable=no-member,protected-access
-    return LayerTypeEnum._value2member_map_.get(endpoint_types.pop())
-
-#a_endpoint = get_endpoint(self.__topology, a_endpoint_key)
-#z_endpoint = get_endpoint(self.__topology, z_endpoint_key)
-#endpoints = [a_endpoint, z_endpoint]
-#layer_type = select_layer_from_endpoints(endpoints)
-#topology = self.__topology if layer_type is None else get_layer(self.__topology, layer_type)
-#write_dot(topology, '../data/layer-{:s}.dot'.format('all' if layer_type is None else str(layer_type.value)))
-
diff --git a/src/service/service/path_computation_element/__init__.py b/src/service/service/path_computation_element/__init__.py
deleted file mode 100644
index 70a33251242c51f49140e596b8208a19dd5245f7..0000000000000000000000000000000000000000
--- a/src/service/service/path_computation_element/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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.
-
diff --git a/src/service/service/service_handlers/l3nm_emulated/ConfigRulesOld.py b/src/service/service/service_handlers/l3nm_emulated/ConfigRulesOld.py
deleted file mode 100644
index 8b12049bae40829ed329c3509bdeaedbf55badb4..0000000000000000000000000000000000000000
--- a/src/service/service/service_handlers/l3nm_emulated/ConfigRulesOld.py
+++ /dev/null
@@ -1,109 +0,0 @@
-
-                # json_endpoint_settings : Dict = endpoint_settings.value
-                # #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
-                # route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
-                # sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
-                # vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
-                # address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
-                # address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
-                # if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
-
-                # db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-                # device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
-                # json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-                # json_device_config : Dict = json_device.setdefault('device_config', {})
-                # json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-                # json_device_config_rules.extend([
-                #     json_config_rule_set(
-                #         '/network_instance[{:s}]'.format(network_instance_name), {
-                #             'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
-                #             'route_distinguisher': route_distinguisher,
-                #             #'router_id': router_id, 'address_families': address_families,
-                #     }),
-                #     json_config_rule_set(
-                #         '/interface[{:s}]'.format(endpoint_uuid), {
-                #             'name': endpoint_uuid, 'description': network_interface_desc, 'mtu': mtu,
-                #     }),
-                #     json_config_rule_set(
-                #         '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
-                #             'name': endpoint_uuid, 'index': sub_interface_index,
-                #             'description': network_subinterface_desc, 'vlan_id': vlan_id,
-                #             'address_ip': address_ip, 'address_prefix': address_prefix,
-                #     }),
-                #     json_config_rule_set(
-                #         '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
-                #             'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
-                #             'subinterface': sub_interface_index,
-                #     }),
-                #     json_config_rule_set(
-                #         '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
-                #             'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
-                #     }),
-                #     json_config_rule_set(
-                #         '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
-                #             'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
-                #             'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
-                #     }),
-                #     json_config_rule_set(
-                #         '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
-                #             network_instance_name), {
-                #             'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
-                #             'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
-                #             'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
-                #             network_instance_name, bgp_route_target), {
-                #             'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                #             'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
-                #             'policy_name': '{:s}_import'.format(network_instance_name),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
-                #             network_instance_name, '3'), {
-                #             'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
-                #             'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                #             'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
-                #     }),
-                #     json_config_rule_set(
-                #         # pylint: disable=duplicate-string-formatting-argument
-                #         '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
-                #             network_instance_name, network_instance_name), {
-                #             'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
-                #             'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
-                #             network_instance_name, bgp_route_target), {
-                #             'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                #             'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
-                #             'policy_name': '{:s}_export'.format(network_instance_name),
-                #     }),
-                #     json_config_rule_set(
-                #         '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
-                #             network_instance_name, '3'), {
-                #             'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
-                #             'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                #             'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
-                #     }),
-                #     json_config_rule_set(
-                #         # pylint: disable=duplicate-string-formatting-argument
-                #         '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
-                #             network_instance_name, network_instance_name), {
-                #             'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
-                #     }),
-                # ])
-                # self.__device_client.ConfigureDevice(Device(**json_device))
-                # results.append(True)
diff --git a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a5aff5884c72f1384666a223a3b07da6d4ae4ec
--- /dev/null
+++ b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py
@@ -0,0 +1,249 @@
+# 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.
+
+from typing import Dict, List
+from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from service.service.service_handler_api.AnyTreeTools import TreeNode
+
+def setup_config_rules(
+    service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str,
+    service_settings : TreeNode, endpoint_settings : TreeNode
+) -> List[Dict]:
+
+    json_settings          : Dict = {} if service_settings  is None else service_settings.value
+    json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value
+
+    service_short_uuid        = service_uuid.split('-')[-1]
+    network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
+    network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
+    network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
+
+    mtu                 = json_settings.get('mtu',                 1450 )    # 1512
+    #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+    bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+    bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
+    #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+    sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+    if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
+
+    json_config_rules = [
+        json_config_rule_set(
+            '/network_instance[{:s}]'.format(network_instance_name), {
+                'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
+                'route_distinguisher': route_distinguisher,
+                #'router_id': router_id, 'address_families': address_families,
+        }),
+        json_config_rule_set(
+            '/interface[{:s}]'.format(endpoint_uuid), {
+                'name': endpoint_uuid, 'description': network_interface_desc, 'mtu': mtu,
+        }),
+        json_config_rule_set(
+            '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
+                'name': endpoint_uuid, 'index': sub_interface_index,
+                'description': network_subinterface_desc, 'vlan_id': vlan_id,
+                'address_ip': address_ip, 'address_prefix': address_prefix,
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
+                'subinterface': sub_interface_index,
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+        }),
+        json_config_rule_set(
+            '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                'policy_name': '{:s}_import'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+        }),
+        json_config_rule_set(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                network_instance_name, network_instance_name), {
+                'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                'policy_name': '{:s}_export'.format(network_instance_name),
+        }),
+        json_config_rule_set(
+            '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+        }),
+        json_config_rule_set(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                network_instance_name, network_instance_name), {
+                'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
+        }),
+    ]
+
+    return json_config_rules
+
+def teardown_config_rules(
+    service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str,
+    service_settings : TreeNode, endpoint_settings : TreeNode
+) -> List[Dict]:
+
+    json_settings          : Dict = {} if service_settings  is None else service_settings.value
+    json_endpoint_settings : Dict = {} if endpoint_settings is None else endpoint_settings.value
+
+    #mtu                 = json_settings.get('mtu',                 1450 )    # 1512
+    #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+    #bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+    bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
+    #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    #route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
+    sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    #address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    #address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+
+    if_subif_name             = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
+    service_short_uuid        = service_uuid.split('-')[-1]
+    network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
+    #network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
+    #network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
+
+    json_config_rules = [
+        json_config_rule_delete(
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                'name': network_instance_name, 'id': if_subif_name,
+        }),
+        json_config_rule_delete(
+            '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
+                'name': endpoint_uuid, 'index': sub_interface_index,
+        }),
+        json_config_rule_delete(
+            '/interface[{:s}]'.format(endpoint_uuid), {
+                'name': endpoint_uuid,
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4',
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                'address_family': 'IPV4',
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
+        }),
+        json_config_rule_delete(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                network_instance_name, network_instance_name), {
+            'name': network_instance_name,
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                'policy_name': '{:s}_import'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            # pylint: disable=duplicate-string-formatting-argument
+            '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                network_instance_name, network_instance_name), {
+                'name': network_instance_name,
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                network_instance_name, '3'), {
+                'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+        }),
+        json_config_rule_delete(
+            '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                'policy_name': '{:s}_export'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                network_instance_name, bgp_route_target), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+        }),
+        json_config_rule_delete(
+            '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+        }),
+        json_config_rule_delete(
+            '/network_instance[{:s}]'.format(network_instance_name), {
+                'name': network_instance_name
+        }),
+    ]
+    return json_config_rules
diff --git a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
index 1faf8e7c25090a79c2d1c7a2bcec7c5db5ba8201..bdf6881647ef1a0861a312496c45512c8734afd9 100644
--- a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
+++ b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
@@ -13,188 +13,66 @@
 # limitations under the License.
 
 import anytree, json, logging
-from typing import Any, Dict, List, Optional, Tuple, Union
-from common.orm.Database import Database
-from common.orm.HighLevel import get_object
-from common.orm.backend.Tools import key_to_str
-from common.proto.context_pb2 import Device
-from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from typing import Any, List, Optional, Tuple, Union
+from common.proto.context_pb2 import ConfigActionEnum, ConfigRule, DeviceId, Service
+from common.tools.object_factory.Device import json_device_id
 from common.type_checkers.Checkers import chk_length, chk_type
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from service.service.database.ConfigModel import ORM_ConfigActionEnum, get_config_rules
-from service.service.database.ContextModel import ContextModel
-from service.service.database.DeviceModel import DeviceModel
-from service.service.database.ServiceModel import ServiceModel
 from service.service.service_handler_api._ServiceHandler import _ServiceHandler
 from service.service.service_handler_api.AnyTreeTools import TreeNode, delete_subnode, get_subnode, set_subnode_value
+from service.service.task_scheduler.TaskExecutor import TaskExecutor
+from .ConfigRules import setup_config_rules, teardown_config_rules
 
 LOGGER = logging.getLogger(__name__)
 
 class L3NMOpenConfigServiceHandler(_ServiceHandler):
     def __init__(   # pylint: disable=super-init-not-called
-        self, db_service : ServiceModel, database : Database, context_client : ContextClient,
-        device_client : DeviceClient, **settings
+        self, service : Service, task_executor : TaskExecutor, **settings
     ) -> None:
-        self.__db_service = db_service
-        self.__database = database
-        self.__context_client = context_client # pylint: disable=unused-private-member
-        self.__device_client = device_client
-
-        self.__db_context : ContextModel = get_object(self.__database, ContextModel, self.__db_service.context_fk)
-        str_service_key = key_to_str([self.__db_context.context_uuid, self.__db_service.service_uuid])
-        db_config = get_config_rules(self.__database, str_service_key, 'running')
+        self.__service = service
+        self.__task_executor = task_executor # pylint: disable=unused-private-member
         self.__resolver = anytree.Resolver(pathattr='name')
         self.__config = TreeNode('.')
-        for action, resource_key, resource_value in db_config:
-            if action == ORM_ConfigActionEnum.SET:
+        for config_rule in service.service_config.config_rules:
+            action = config_rule.action
+            if config_rule.WhichOneof('config_rule') != 'custom': continue
+            resource_key = config_rule.custom.resource_key
+            resource_value = config_rule.custom.resource_value
+            if action == ConfigActionEnum.CONFIGACTION_SET:
                 try:
                     resource_value = json.loads(resource_value)
                 except: # pylint: disable=bare-except
                     pass
                 set_subnode_value(self.__resolver, self.__config, resource_key, resource_value)
-            elif action == ORM_ConfigActionEnum.DELETE:
+            elif action == ConfigActionEnum.CONFIGACTION_DELETE:
                 delete_subnode(self.__resolver, self.__config, resource_key)
 
-    def SetEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
+    def SetEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
         chk_type('endpoints', endpoints, list)
         if len(endpoints) == 0: return []
 
-        service_uuid              = self.__db_service.service_uuid
-        service_short_uuid        = service_uuid.split('-')[-1]
-        network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
-        network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
-        network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
-
+        service_uuid = self.__service.service_id.service_uuid.uuid
         settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
-        if settings is None: raise Exception('Unable to retrieve service settings')
-        json_settings : Dict = settings.value
-        mtu                 = json_settings.get('mtu',                 1450 )    # 1512
-        #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
-        bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
-        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
 
         results = []
         for endpoint in endpoints:
             try:
                 chk_type('endpoint', endpoint, (tuple, list))
                 chk_length('endpoint', endpoint, min_length=2, max_length=3)
-                if len(endpoint) == 2:
-                    device_uuid, endpoint_uuid = endpoint
-                else:
-                    device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
+                device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
 
                 endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
-                if endpoint_settings is None:
-                    raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
-                        str(endpoint_settings_uri)))
-                json_endpoint_settings : Dict = endpoint_settings.value
-                #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
-                route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
-                sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
-                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
-                address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
-                address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
-                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
-                db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-                json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-                json_device_config : Dict = json_device.setdefault('device_config', {})
-                json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-                json_device_config_rules.extend([
-                    json_config_rule_set(
-                        '/network_instance[{:s}]'.format(network_instance_name), {
-                            'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
-                            'route_distinguisher': route_distinguisher,
-                            #'router_id': router_id, 'address_families': address_families,
-                    }),
-                    json_config_rule_set(
-                        '/interface[{:s}]'.format(endpoint_uuid), {
-                            'name': endpoint_uuid, 'description': network_interface_desc, 'mtu': mtu,
-                    }),
-                    json_config_rule_set(
-                        '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
-                            'name': endpoint_uuid, 'index': sub_interface_index,
-                            'description': network_subinterface_desc, 'vlan_id': vlan_id,
-                            'address_ip': address_ip, 'address_prefix': address_prefix,
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
-                            'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
-                            'subinterface': sub_interface_index,
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
-                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
-                            network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
-                            'policy_name': '{:s}_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
-                            network_instance_name, network_instance_name), {
-                            'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
-                            'policy_name': '{:s}_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_set(
-                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
-                    }),
-                    json_config_rule_set(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
-                            network_instance_name, network_instance_name), {
-                            'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
-                    }),
-                ])
-                self.__device_client.ConfigureDevice(Device(**json_device))
+                json_config_rules = setup_config_rules(
+                    service_uuid, connection_uuid, device_uuid, endpoint_uuid, settings, endpoint_settings)
+
+                device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                del device.device_config.config_rules[:]
+                for json_config_rule in json_config_rules:
+                    device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+                self.__task_executor.configure_device(device)
                 results.append(True)
             except Exception as e: # pylint: disable=broad-except
                 LOGGER.exception('Unable to SetEndpoint({:s})'.format(str(endpoint)))
@@ -202,127 +80,33 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
 
         return results
 
-    def DeleteEndpoint(self, endpoints : List[Tuple[str, str, Optional[str]]]) -> List[Union[bool, Exception]]:
+    def DeleteEndpoint(
+        self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None
+    ) -> List[Union[bool, Exception]]:
         chk_type('endpoints', endpoints, list)
         if len(endpoints) == 0: return []
 
-        service_uuid              = self.__db_service.service_uuid
-        service_short_uuid        = service_uuid.split('-')[-1]
-        network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
-
+        service_uuid = self.__service.service_id.service_uuid.uuid
         settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
-        if settings is None: raise Exception('Unable to retrieve service settings')
-        json_settings : Dict = settings.value
-        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
 
         results = []
         for endpoint in endpoints:
             try:
                 chk_type('endpoint', endpoint, (tuple, list))
                 chk_length('endpoint', endpoint, min_length=2, max_length=3)
-                if len(endpoint) == 2:
-                    device_uuid, endpoint_uuid = endpoint
-                else:
-                    device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
+                device_uuid, endpoint_uuid = endpoint[0:2] # ignore topology_uuid by now
 
                 endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
-                if endpoint_settings is None:
-                    raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
-                        str(endpoint_settings_uri)))
-                json_endpoint_settings : Dict = endpoint_settings.value
-                sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
-                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
-                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
-                db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
-                json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
-                json_device_config : Dict = json_device.setdefault('device_config', {})
-                json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
-                json_device_config_rules.extend([
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
-                            'name': network_instance_name, 'id': if_subif_name,
-                    }),
-                    json_config_rule_delete(
-                        '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
-                            'name': endpoint_uuid, 'index': sub_interface_index,
-                    }),
-                    json_config_rule_delete(
-                        '/interface[{:s}]'.format(endpoint_uuid), {
-                            'name': endpoint_uuid,
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
-                            network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4',
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
-                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
-                            'address_family': 'IPV4',
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
-                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
-                    }),
-                    json_config_rule_delete(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
-                            network_instance_name, network_instance_name), {
-                        'name': network_instance_name,
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
-                            'policy_name': '{:s}_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        # pylint: disable=duplicate-string-formatting-argument
-                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
-                            network_instance_name, network_instance_name), {
-                            'name': network_instance_name,
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
-                            network_instance_name, '3'), {
-                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
-                            'policy_name': '{:s}_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
-                            network_instance_name, bgp_route_target), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
-                    }),
-                    json_config_rule_delete(
-                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
-                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
-                    }),
-                    json_config_rule_delete(
-                        '/network_instance[{:s}]'.format(network_instance_name), {
-                            'name': network_instance_name
-                    }),
-                ])
-                self.__device_client.ConfigureDevice(Device(**json_device))
+                json_config_rules = teardown_config_rules(
+                    service_uuid, connection_uuid, device_uuid, endpoint_uuid, settings, endpoint_settings)
+
+                device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                del device.device_config.config_rules[:]
+                for json_config_rule in json_config_rules:
+                    device.device_config.config_rules.append(ConfigRule(**json_config_rule))
+                self.__task_executor.configure_device(device)
                 results.append(True)
             except Exception as e: # pylint: disable=broad-except
                 LOGGER.exception('Unable to DeleteEndpoint({:s})'.format(str(endpoint)))