diff --git a/scripts/run_tests_locally-nbi-debug-api.sh b/scripts/run_tests_locally-nbi-debug-api.sh
new file mode 100755
index 0000000000000000000000000000000000000000..218bad8c57b508cee4fc5cfe40f0f6d484dff32e
--- /dev/null
+++ b/scripts/run_tests_locally-nbi-debug-api.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    nbi/tests/test_debug_api.py
diff --git a/src/common/tests/MockServicerImpl_Context.py b/src/common/tests/MockServicerImpl_Context.py
index 98a216850a757e0c21c44d2e295cb4b93c538e05..464517a767f31d95277dc8205cf49f527fe96a48 100644
--- a/src/common/tests/MockServicerImpl_Context.py
+++ b/src/common/tests/MockServicerImpl_Context.py
@@ -25,12 +25,13 @@ from common.proto.context_pb2 import (
     Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
     Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList)
 from common.proto.context_pb2_grpc import ContextServiceServicer
+from common.proto.policy_pb2 import PolicyRule, PolicyRuleId, PolicyRuleIdList, PolicyRuleList
 from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string
 from common.tools.object_factory.Device import json_device_id
 from common.tools.object_factory.Link import json_link_id
 from .InMemoryObjectDatabase import InMemoryObjectDatabase
 from .MockMessageBroker import (
-    TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE, TOPIC_TOPOLOGY,
+    TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE, TOPIC_TOPOLOGY, TOPIC_POLICY,
     MockMessageBroker, notify_event)
 
 LOGGER = logging.getLogger(__name__)
@@ -62,58 +63,58 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
     # ----- Context ----------------------------------------------------------------------------------------------------
 
-    def ListContextIds(self, request: Empty, context : grpc.ServicerContext) -> ContextIdList:
+    def ListContextIds(self, request : Empty, context : grpc.ServicerContext) -> ContextIdList:
         LOGGER.debug('[ListContextIds] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = ContextIdList(context_ids=[context.context_id for context in self.obj_db.get_entries('context')])
         LOGGER.debug('[ListContextIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListContexts(self, request: Empty, context : grpc.ServicerContext) -> ContextList:
+    def ListContexts(self, request : Empty, context : grpc.ServicerContext) -> ContextList:
         LOGGER.debug('[ListContexts] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = ContextList(contexts=self.obj_db.get_entries('context'))
         LOGGER.debug('[ListContexts] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetContext(self, request: ContextId, context : grpc.ServicerContext) -> Context:
+    def GetContext(self, request : ContextId, context : grpc.ServicerContext) -> Context:
         LOGGER.debug('[GetContext] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = self.obj_db.get_entry('context', request.context_uuid.uuid, context)
         LOGGER.debug('[GetContext] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetContext(self, request: Context, context : grpc.ServicerContext) -> ContextId:
+    def SetContext(self, request : Context, context : grpc.ServicerContext) -> ContextId:
         LOGGER.debug('[SetContext] request={:s}'.format(grpc_message_to_json_string(request)))
         reply,_ = self._set(request, 'context', request.context_id.context_uuid.uuid, 'context_id', TOPIC_CONTEXT)
         LOGGER.debug('[SetContext] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveContext(self, request: ContextId, context : grpc.ServicerContext) -> Empty:
+    def RemoveContext(self, request : ContextId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveContext] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = self._del(request, 'context', request.context_uuid.uuid, 'context_id', TOPIC_CONTEXT, context)
         LOGGER.debug('[RemoveContext] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetContextEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[ContextEvent]:
+    def GetContextEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[ContextEvent]:
         LOGGER.debug('[GetContextEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_CONTEXT}): yield ContextEvent(**json.loads(message.content))
 
 
     # ----- Topology ---------------------------------------------------------------------------------------------------
 
-    def ListTopologyIds(self, request: ContextId, context : grpc.ServicerContext) -> TopologyIdList:
+    def ListTopologyIds(self, request : ContextId, context : grpc.ServicerContext) -> TopologyIdList:
         LOGGER.debug('[ListTopologyIds] request={:s}'.format(grpc_message_to_json_string(request)))
         topologies = self.obj_db.get_entries('topology[{:s}]'.format(str(request.context_uuid.uuid)))
         reply = TopologyIdList(topology_ids=[topology.topology_id for topology in topologies])
         LOGGER.debug('[ListTopologyIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListTopologies(self, request: ContextId, context : grpc.ServicerContext) -> TopologyList:
+    def ListTopologies(self, request : ContextId, context : grpc.ServicerContext) -> TopologyList:
         LOGGER.debug('[ListTopologies] request={:s}'.format(grpc_message_to_json_string(request)))
         topologies = self.obj_db.get_entries('topology[{:s}]'.format(str(request.context_uuid.uuid)))
         reply = TopologyList(topologies=[topology for topology in topologies])
         LOGGER.debug('[ListTopologies] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetTopology(self, request: TopologyId, context : grpc.ServicerContext) -> Topology:
+    def GetTopology(self, request : TopologyId, context : grpc.ServicerContext) -> Topology:
         LOGGER.debug('[GetTopology] request={:s}'.format(grpc_message_to_json_string(request)))
         container_name = 'topology[{:s}]'.format(str(request.context_id.context_uuid.uuid))
         reply = self.obj_db.get_entry(container_name, request.topology_uuid.uuid, context)
@@ -143,7 +144,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[GetTopologyDetails] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetTopology(self, request: Topology, context : grpc.ServicerContext) -> TopologyId:
+    def SetTopology(self, request : Topology, context : grpc.ServicerContext) -> TopologyId:
         LOGGER.debug('[SetTopology] request={:s}'.format(grpc_message_to_json_string(request)))
         context_uuid = str(request.topology_id.context_id.context_uuid.uuid)
         container_name = 'topology[{:s}]'.format(context_uuid)
@@ -164,10 +165,12 @@ class MockServicerImpl_Context(ContextServiceServicer):
             rw_request = Topology()
             rw_request.CopyFrom(request)
 
+            # pylint: disable=no-member
             del rw_request.device_ids[:]
             for device_uuid in sorted(device_uuids):
                 rw_request.device_ids.append(DeviceId(**json_device_id(device_uuid)))
 
+            # pylint: disable=no-member
             del rw_request.link_ids[:]
             for link_uuid in sorted(link_uuids):
                 rw_request.link_ids.append(LinkId(**json_link_id(link_uuid)))
@@ -181,12 +184,14 @@ class MockServicerImpl_Context(ContextServiceServicer):
             if _topology_id.topology_uuid.uuid == topology_uuid: break
         else:
             # topology not found, add it
-            context_.topology_ids.add().topology_uuid.uuid = topology_uuid
+            topology_id = context_.topology_ids.add()
+            topology_id.context_id.context_uuid.uuid = context_uuid
+            topology_id.topology_uuid.uuid = topology_uuid
 
         LOGGER.debug('[SetTopology] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveTopology(self, request: TopologyId, context : grpc.ServicerContext) -> Empty:
+    def RemoveTopology(self, request : TopologyId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveTopology] request={:s}'.format(grpc_message_to_json_string(request)))
         context_uuid = str(request.context_id.context_uuid.uuid)
         container_name = 'topology[{:s}]'.format(context_uuid)
@@ -195,39 +200,40 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
         context_ = self.obj_db.get_entry('context', context_uuid, context)
         for _topology_id in context_.topology_ids:
-            if _topology_id.topology_uuid.uuid == topology_uuid:
-                context_.topology_ids.remove(_topology_id)
-                break
+            if _topology_id.context_id.context_uuid.uuid != context_uuid: continue
+            if _topology_id.topology_uuid.uuid != topology_uuid: continue
+            context_.topology_ids.remove(_topology_id)
+            break
 
         LOGGER.debug('[RemoveTopology] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetTopologyEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[TopologyEvent]:
+    def GetTopologyEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[TopologyEvent]:
         LOGGER.debug('[GetTopologyEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_TOPOLOGY}): yield TopologyEvent(**json.loads(message.content))
 
 
     # ----- Device -----------------------------------------------------------------------------------------------------
 
-    def ListDeviceIds(self, request: Empty, context : grpc.ServicerContext) -> DeviceIdList:
+    def ListDeviceIds(self, request : Empty, context : grpc.ServicerContext) -> DeviceIdList:
         LOGGER.debug('[ListDeviceIds] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = DeviceIdList(device_ids=[device.device_id for device in self.obj_db.get_entries('device')])
         LOGGER.debug('[ListDeviceIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListDevices(self, request: Empty, context : grpc.ServicerContext) -> DeviceList:
+    def ListDevices(self, request : Empty, context : grpc.ServicerContext) -> DeviceList:
         LOGGER.debug('[ListDevices] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = DeviceList(devices=self.obj_db.get_entries('device'))
         LOGGER.debug('[ListDevices] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetDevice(self, request: DeviceId, context : grpc.ServicerContext) -> Device:
+    def GetDevice(self, request : DeviceId, context : grpc.ServicerContext) -> Device:
         LOGGER.debug('[GetDevice] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = self.obj_db.get_entry('device', request.device_uuid.uuid, context)
         LOGGER.debug('[GetDevice] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetDevice(self, request: Context, context : grpc.ServicerContext) -> DeviceId:
+    def SetDevice(self, request : Context, context : grpc.ServicerContext) -> DeviceId:
         LOGGER.debug('[SetDevice] request={:s}'.format(grpc_message_to_json_string(request)))
         device_uuid = request.device_id.device_uuid.uuid
         reply, device = self._set(request, 'device', device_uuid, 'device_id', TOPIC_DEVICE)
@@ -253,7 +259,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[SetDevice] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveDevice(self, request: DeviceId, context : grpc.ServicerContext) -> Empty:
+    def RemoveDevice(self, request : DeviceId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveDevice] request={:s}'.format(grpc_message_to_json_string(request)))
         device_uuid = request.device_uuid.uuid
         device = self.obj_db.get_entry('device', device_uuid, context)
@@ -279,7 +285,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[RemoveDevice] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetDeviceEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[DeviceEvent]:
+    def GetDeviceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[DeviceEvent]:
         LOGGER.debug('[GetDeviceEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_DEVICE}): yield DeviceEvent(**json.loads(message.content))
 
@@ -313,25 +319,25 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
     # ----- Link -------------------------------------------------------------------------------------------------------
 
-    def ListLinkIds(self, request: Empty, context : grpc.ServicerContext) -> LinkIdList:
+    def ListLinkIds(self, request : Empty, context : grpc.ServicerContext) -> LinkIdList:
         LOGGER.debug('[ListLinkIds] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = LinkIdList(link_ids=[link.link_id for link in self.obj_db.get_entries('link')])
         LOGGER.debug('[ListLinkIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListLinks(self, request: Empty, context : grpc.ServicerContext) -> LinkList:
+    def ListLinks(self, request : Empty, context : grpc.ServicerContext) -> LinkList:
         LOGGER.debug('[ListLinks] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = LinkList(links=self.obj_db.get_entries('link'))
         LOGGER.debug('[ListLinks] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetLink(self, request: LinkId, context : grpc.ServicerContext) -> Link:
+    def GetLink(self, request : LinkId, context : grpc.ServicerContext) -> Link:
         LOGGER.debug('[GetLink] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = self.obj_db.get_entry('link', request.link_uuid.uuid, context)
         LOGGER.debug('[GetLink] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetLink(self, request: Context, context : grpc.ServicerContext) -> LinkId:
+    def SetLink(self, request : Context, context : grpc.ServicerContext) -> LinkId:
         LOGGER.debug('[SetLink] request={:s}'.format(grpc_message_to_json_string(request)))
         link_uuid = request.link_id.link_uuid.uuid
         reply, link = self._set(request, 'link', link_uuid, 'link_id', TOPIC_LINK)
@@ -357,7 +363,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[SetLink] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveLink(self, request: LinkId, context : grpc.ServicerContext) -> Empty:
+    def RemoveLink(self, request : LinkId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveLink] request={:s}'.format(grpc_message_to_json_string(request)))
         link_uuid = request.link_uuid.uuid
         link = self.obj_db.get_entry('link', link_uuid, context)
@@ -383,35 +389,35 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[RemoveLink] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetLinkEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[LinkEvent]:
+    def GetLinkEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[LinkEvent]:
         LOGGER.debug('[GetLinkEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_LINK}): yield LinkEvent(**json.loads(message.content))
 
 
     # ----- Slice ------------------------------------------------------------------------------------------------------
 
-    def ListSliceIds(self, request: ContextId, context : grpc.ServicerContext) -> SliceIdList:
+    def ListSliceIds(self, request : ContextId, context : grpc.ServicerContext) -> SliceIdList:
         LOGGER.debug('[ListSliceIds] request={:s}'.format(grpc_message_to_json_string(request)))
         slices = self.obj_db.get_entries('slice[{:s}]'.format(str(request.context_uuid.uuid)))
         reply = SliceIdList(slice_ids=[slice.slice_id for slice in slices])
         LOGGER.debug('[ListSliceIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListSlices(self, request: ContextId, context : grpc.ServicerContext) -> SliceList:
+    def ListSlices(self, request : ContextId, context : grpc.ServicerContext) -> SliceList:
         LOGGER.debug('[ListSlices] request={:s}'.format(grpc_message_to_json_string(request)))
         slices = self.obj_db.get_entries('slice[{:s}]'.format(str(request.context_uuid.uuid)))
         reply = SliceList(slices=[slice for slice in slices])
         LOGGER.debug('[ListSlices] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetSlice(self, request: SliceId, context : grpc.ServicerContext) -> Slice:
+    def GetSlice(self, request : SliceId, context : grpc.ServicerContext) -> Slice:
         LOGGER.debug('[GetSlice] request={:s}'.format(grpc_message_to_json_string(request)))
         container_name = 'slice[{:s}]'.format(str(request.context_id.context_uuid.uuid))
         reply = self.obj_db.get_entry(container_name, request.slice_uuid.uuid, context)
         LOGGER.debug('[GetSlice] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetSlice(self, request: Slice, context : grpc.ServicerContext) -> SliceId:
+    def SetSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
         LOGGER.debug('[SetSlice] request={:s}'.format(grpc_message_to_json_string(request)))
         context_uuid = str(request.slice_id.context_id.context_uuid.uuid)
         container_name = 'slice[{:s}]'.format(context_uuid)
@@ -423,12 +429,14 @@ class MockServicerImpl_Context(ContextServiceServicer):
             if _slice_id.slice_uuid.uuid == slice_uuid: break
         else:
             # slice not found, add it
-            context_.slice_ids.add().slice_uuid.uuid = slice_uuid
+            slice_id = context_.slice_ids.add()
+            slice_id.context_id.context_uuid.uuid = context_uuid
+            slice_id.slice_uuid.uuid = slice_uuid
 
         LOGGER.debug('[SetSlice] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveSlice(self, request: SliceId, context : grpc.ServicerContext) -> Empty:
+    def RemoveSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveSlice] request={:s}'.format(grpc_message_to_json_string(request)))
         context_uuid = str(request.context_id.context_uuid.uuid)
         container_name = 'slice[{:s}]'.format(context_uuid)
@@ -437,14 +445,15 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
         context_ = self.obj_db.get_entry('context', context_uuid, context)
         for _slice_id in context_.slice_ids:
-            if _slice_id.slice_uuid.uuid == slice_uuid:
-                context_.slice_ids.remove(_slice_id)
-                break
+            if _slice_id.context_id.context_uuid.uuid != context_uuid: continue
+            if _slice_id.slice_uuid.uuid != slice_uuid: continue
+            context_.slice_ids.remove(_slice_id)
+            break
 
         LOGGER.debug('[RemoveSlice] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetSliceEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[SliceEvent]:
+    def GetSliceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[SliceEvent]:
         LOGGER.debug('[GetSliceEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_SLICE}): yield SliceEvent(**json.loads(message.content))
 
@@ -482,28 +491,28 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
     # ----- Service ----------------------------------------------------------------------------------------------------
 
-    def ListServiceIds(self, request: ContextId, context : grpc.ServicerContext) -> ServiceIdList:
+    def ListServiceIds(self, request : ContextId, context : grpc.ServicerContext) -> ServiceIdList:
         LOGGER.debug('[ListServiceIds] request={:s}'.format(grpc_message_to_json_string(request)))
         services = self.obj_db.get_entries('service[{:s}]'.format(str(request.context_uuid.uuid)))
         reply = ServiceIdList(service_ids=[service.service_id for service in services])
         LOGGER.debug('[ListServiceIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListServices(self, request: ContextId, context : grpc.ServicerContext) -> ServiceList:
+    def ListServices(self, request : ContextId, context : grpc.ServicerContext) -> ServiceList:
         LOGGER.debug('[ListServices] request={:s}'.format(grpc_message_to_json_string(request)))
         services = self.obj_db.get_entries('service[{:s}]'.format(str(request.context_uuid.uuid)))
         reply = ServiceList(services=[service for service in services])
         LOGGER.debug('[ListServices] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetService(self, request: ServiceId, context : grpc.ServicerContext) -> Service:
+    def GetService(self, request : ServiceId, context : grpc.ServicerContext) -> Service:
         LOGGER.debug('[GetService] request={:s}'.format(grpc_message_to_json_string(request)))
         container_name = 'service[{:s}]'.format(str(request.context_id.context_uuid.uuid))
         reply = self.obj_db.get_entry(container_name, request.service_uuid.uuid, context)
         LOGGER.debug('[GetService] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetService(self, request: Service, context : grpc.ServicerContext) -> ServiceId:
+    def SetService(self, request : Service, context : grpc.ServicerContext) -> ServiceId:
         LOGGER.debug('[SetService] request={:s}'.format(grpc_message_to_json_string(request)))
         context_uuid = str(request.service_id.context_id.context_uuid.uuid)
         container_name = 'service[{:s}]'.format(context_uuid)
@@ -515,12 +524,14 @@ class MockServicerImpl_Context(ContextServiceServicer):
             if _service_id.service_uuid.uuid == service_uuid: break
         else:
             # service not found, add it
-            context_.service_ids.add().service_uuid.uuid = service_uuid
+            service_id = context_.service_ids.add()
+            service_id.context_id.context_uuid.uuid = context_uuid
+            service_id.service_uuid.uuid = service_uuid
 
         LOGGER.debug('[SetService] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveService(self, request: ServiceId, context : grpc.ServicerContext) -> Empty:
+    def RemoveService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveService] request={:s}'.format(grpc_message_to_json_string(request)))
         context_uuid = str(request.context_id.context_uuid.uuid)
         container_name = 'service[{:s}]'.format(context_uuid)
@@ -529,14 +540,15 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
         context_ = self.obj_db.get_entry('context', context_uuid, context)
         for _service_id in context_.service_ids:
-            if _service_id.service_uuid.uuid == service_uuid:
-                context_.service_ids.remove(_service_id)
-                break
+            if _service_id.context_id.context_uuid.uuid != context_uuid: continue
+            if _service_id.service_uuid.uuid != service_uuid: continue
+            context_.service_ids.remove(_service_id)
+            break
 
         LOGGER.debug('[RemoveService] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetServiceEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[ServiceEvent]:
+    def GetServiceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[ServiceEvent]:
         LOGGER.debug('[GetServiceEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_SERVICE}): yield ServiceEvent(**json.loads(message.content))
 
@@ -569,7 +581,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
 
     # ----- Connection -------------------------------------------------------------------------------------------------
 
-    def ListConnectionIds(self, request: ServiceId, context : grpc.ServicerContext) -> ConnectionIdList:
+    def ListConnectionIds(self, request : ServiceId, context : grpc.ServicerContext) -> ConnectionIdList:
         LOGGER.debug('[ListConnectionIds] request={:s}'.format(grpc_message_to_json_string(request)))
         container_name = 'service_connections[{:s}/{:s}]'.format(
             str(request.context_id.context_uuid.uuid), str(request.service_uuid.uuid))
@@ -577,7 +589,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[ListConnectionIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def ListConnections(self, request: ServiceId, context : grpc.ServicerContext) -> ConnectionList:
+    def ListConnections(self, request : ServiceId, context : grpc.ServicerContext) -> ConnectionList:
         LOGGER.debug('[ListConnections] request={:s}'.format(grpc_message_to_json_string(request)))
         container_name = 'service_connections[{:s}/{:s}]'.format(
             str(request.context_id.context_uuid.uuid), str(request.service_uuid.uuid))
@@ -585,13 +597,13 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[ListConnections] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetConnection(self, request: ConnectionId, context : grpc.ServicerContext) -> Connection:
+    def GetConnection(self, request : ConnectionId, context : grpc.ServicerContext) -> Connection:
         LOGGER.debug('[GetConnection] request={:s}'.format(grpc_message_to_json_string(request)))
         reply = self.obj_db.get_entry('connection', request.connection_uuid.uuid, context)
         LOGGER.debug('[GetConnection] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def SetConnection(self, request: Connection, context : grpc.ServicerContext) -> ConnectionId:
+    def SetConnection(self, request : Connection, context : grpc.ServicerContext) -> ConnectionId:
         LOGGER.debug('[SetConnection] request={:s}'.format(grpc_message_to_json_string(request)))
         container_name = 'service_connection[{:s}/{:s}]'.format(
             str(request.service_id.context_id.context_uuid.uuid), str(request.service_id.service_uuid.uuid))
@@ -601,7 +613,7 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[SetConnection] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def RemoveConnection(self, request: ConnectionId, context : grpc.ServicerContext) -> Empty:
+    def RemoveConnection(self, request : ConnectionId, context : grpc.ServicerContext) -> Empty:
         LOGGER.debug('[RemoveConnection] request={:s}'.format(grpc_message_to_json_string(request)))
         connection = self.obj_db.get_entry('connection', request.connection_uuid.uuid, context)
         container_name = 'service_connection[{:s}/{:s}]'.format(
@@ -612,6 +624,45 @@ class MockServicerImpl_Context(ContextServiceServicer):
         LOGGER.debug('[RemoveConnection] reply={:s}'.format(grpc_message_to_json_string(reply)))
         return reply
 
-    def GetConnectionEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[ConnectionEvent]:
+    def GetConnectionEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[ConnectionEvent]:
         LOGGER.debug('[GetConnectionEvents] request={:s}'.format(grpc_message_to_json_string(request)))
         for message in self.msg_broker.consume({TOPIC_CONNECTION}): yield ConnectionEvent(**json.loads(message.content))
+
+    def ListPolicyRuleIds(self, request : Empty, context : grpc.ServicerContext):   # pylint: disable=unused-argument
+        LOGGER.debug('[ListPolicyRuleIds] request={:s}'.format(grpc_message_to_json_string(request)))
+        reply = PolicyRuleIdList(policyRuleIdList=[
+            getattr(policy_rule, policy_rule.WhichOneof('policy_rule')).policyRuleBasic.policyRuleId
+            for policy_rule in self.obj_db.get_entries('policy')
+        ])
+        LOGGER.debug('[ListPolicyRuleIds] reply={:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
+
+    def ListPolicyRules(self, request : Empty, context : grpc.ServicerContext):     # pylint: disable=unused-argument
+        LOGGER.debug('[ListPolicyRules] request={:s}'.format(grpc_message_to_json_string(request)))
+        reply = PolicyRuleList(policyRules=self.obj_db.get_entries('policy'))
+        LOGGER.debug('[ListPolicyRules] reply={:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
+
+    def GetPolicyRule(self, request : PolicyRuleId, context : grpc.ServicerContext):
+        LOGGER.debug('[GetPolicyRule] request={:s}'.format(grpc_message_to_json_string(request)))
+        reply = self.obj_db.get_entry('policy_rule', request.uuid.uuid, context)
+        LOGGER.debug('[GetPolicyRule] reply={:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
+
+    def SetPolicyRule(self, request : PolicyRule, context : grpc.ServicerContext):  # pylint: disable=unused-argument
+        LOGGER.debug('[SetPolicyRule] request={:s}'.format(grpc_message_to_json_string(request)))
+        policy_type = request.WhichOneof('policy_rule')
+        policy_uuid = getattr(request, policy_type).policyRuleBasic.policyRuleId.uuid.uuid
+        rule_id_field = '{:s}.policyRuleBasic.policyRuleId'.format(policy_type)
+        reply, _ = self._set(request, 'policy', policy_uuid, rule_id_field, TOPIC_POLICY)
+        LOGGER.debug('[SetPolicyRule] reply={:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
+
+    def RemovePolicyRule(self, request : PolicyRuleId, context : grpc.ServicerContext):
+        LOGGER.debug('[RemovePolicyRule] request={:s}'.format(grpc_message_to_json_string(request)))
+        policy_type = request.WhichOneof('policy_rule')
+        policy_uuid = getattr(request, policy_type).policyRuleBasic.policyRuleId.uuid.uuid
+        rule_id_field = '{:s}.policyRuleBasic.policyRuleId'.format(policy_type)
+        reply = self._del(request, 'policy', policy_uuid, rule_id_field, TOPIC_CONTEXT, context)
+        LOGGER.debug('[RemovePolicyRule] reply={:s}'.format(grpc_message_to_json_string(reply)))
+        return reply
diff --git a/src/common/type_checkers/Assertions.py b/src/common/type_checkers/Assertions.py
index 8b7d5ff03cab348e89206a5e47d3d6e88e66b32f..87d8e54ee390fb1f56266317be5317731bb755b6 100644
--- a/src/common/type_checkers/Assertions.py
+++ b/src/common/type_checkers/Assertions.py
@@ -12,7 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from typing import Dict
+import logging
+from typing import Callable, Dict
+
+LOGGER = logging.getLogger(__name__)
 
 # ----- Enumerations ---------------------------------------------------------------------------------------------------
 def validate_config_action_enum(message):
@@ -23,6 +26,14 @@ def validate_config_action_enum(message):
         'CONFIGACTION_DELETE',
     ]
 
+def validate_constraint_action_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'CONSTRAINTACTION_UNDEFINED',
+        'CONSTRAINTACTION_SET',
+        'CONSTRAINTACTION_DELETE',
+    ]
+
 def validate_device_driver_enum(message):
     assert isinstance(message, str)
     assert message in [
@@ -66,6 +77,8 @@ def validate_service_type_enum(message):
         'SERVICETYPE_L3NM',
         'SERVICETYPE_L2NM',
         'SERVICETYPE_TAPI_CONNECTIVITY_SERVICE',
+        'SERVICETYPE_TE',
+        'SERVICETYPE_E2E',
     ]
 
 def validate_service_state_enum(message):
@@ -79,6 +92,17 @@ def validate_service_state_enum(message):
         'SERVICESTATUS_SLA_VIOLATED',
     ]
 
+def validate_slice_status_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'SLICESTATUS_UNDEFINED',
+        'SLICESTATUS_PLANNED',
+        'SLICESTATUS_INIT',
+        'SLICESTATUS_ACTIVE',
+        'SLICESTATUS_DEINIT',
+        'SLICESTATUS_SLA_VIOLATED',
+    ]
+
 
 # ----- Common ---------------------------------------------------------------------------------------------------------
 def validate_uuid(message, allow_empty=False):
@@ -116,28 +140,61 @@ def validate_config_rules(message):
     assert 'config_rules' in message
     for config_rule in message['config_rules']: validate_config_rule(config_rule)
 
-CONSTRAINT_TYPES = {
-    'custom',
-    'schedule',
-    'endpoint_location',
-    'sla_capacity',
-    'sla_latency',
-    'sla_availability',
-    'sla_isolation',
+def validate_constraint_custom(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 2
+    assert 'constraint_type' in message
+    assert isinstance(message['constraint_type'], str)
+    assert 'constraint_value' in message
+    assert isinstance(message['constraint_value'], str)
+
+def validate_constraint_sla_capacity(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'capacity_gbps' in message
+    assert isinstance(message['capacity_gbps'], (int, float))
+
+def validate_constraint_sla_latency(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'e2e_latency_ms' in message
+    assert isinstance(message['e2e_latency_ms'], (int, float))
+
+def validate_constraint_sla_availability(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 3
+    assert 'num_disjoint_paths' in message
+    assert isinstance(message['num_disjoint_paths'], int)
+    assert message['num_disjoint_paths'] >= 0
+    assert 'all_active' in message
+    assert isinstance(message['all_active'], bool)
+    assert 'availability' in message
+    assert isinstance(message['availability'], (int, float))
+    assert message['availability'] >= 0 and message['availability'] <= 100
+
+CONSTRAINT_TYPE_TO_VALIDATOR = {
+    'custom'            : validate_constraint_custom,
+    #'schedule'          : validate_constraint_schedule,
+    #'endpoint_location' : validate_constraint_endpoint_location,
+    #'endpoint_priority' : validate_constraint_endpoint_priority,
+    'sla_capacity'      : validate_constraint_sla_capacity,
+    'sla_latency'       : validate_constraint_sla_latency,
+    'sla_availability'  : validate_constraint_sla_availability,
+    #'sla_isolation'     : validate_constraint_sla_isolation,
+    #'exclusions'        : validate_constraint_exclusions,
 }
+
 def validate_constraint(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 1
-    other_keys = list(message.keys())
-    constraint_type = other_keys[0]
-    assert constraint_type in CONSTRAINT_TYPES
-    assert constraint_type == 'custom', 'Constraint Type Validator for {:s} not implemented'.format(constraint_type)
-    custom : Dict = message['custom']
-    assert len(custom.keys()) == 2
-    assert 'constraint_type' in custom
-    assert isinstance(custom['constraint_type'], str)
-    assert 'constraint_value' in custom
-    assert isinstance(custom['constraint_value'], str)
+    assert len(message.keys()) == 2
+    assert 'action' in message
+    validate_constraint_action_enum(message['action'])
+    other_keys = set(list(message.keys()))
+    other_keys.discard('action')
+    constraint_type = other_keys.pop()
+    validator : Callable = CONSTRAINT_TYPE_TO_VALIDATOR.get(constraint_type)
+    assert validator is not None, 'Constraint Type Validator for {:s} not implemented'.format(constraint_type)
+    validator(message[constraint_type])
 
 
 # ----- Identifiers ----------------------------------------------------------------------------------------------------
@@ -194,6 +251,15 @@ def validate_connection_id(message):
     assert 'connection_uuid' in message
     validate_uuid(message['connection_uuid'])
 
+def validate_slice_id(message, context_uuid = None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 2
+    assert 'context_id' in message
+    validate_context_id(message['context_id'])
+    if context_uuid is not None: assert message['context_id']['context_uuid']['uuid'] == context_uuid
+    assert 'slice_uuid' in message
+    validate_uuid(message['slice_uuid'])
+
 
 # ----- Lists of Identifiers -------------------------------------------------------------------------------------------
 
@@ -211,6 +277,13 @@ def validate_service_ids(message, context_uuid=None):
     assert isinstance(message['service_ids'], list)
     for service_id in message['service_ids']: validate_service_id(service_id, context_uuid=context_uuid)
 
+def validate_slice_ids(message, context_uuid=None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'slice_ids' in message
+    assert isinstance(message['slice_ids'], list)
+    for slice_id in message['slice_ids']: validate_slice_id(slice_id, context_uuid=context_uuid)
+
 def validate_topology_ids(message, context_uuid=None):
     assert isinstance(message, dict)
     assert len(message.keys()) == 1
@@ -244,16 +317,21 @@ def validate_connection_ids(message):
 
 def validate_context(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 3
+    assert len(message.keys()) == 5
     assert 'context_id' in message
     validate_context_id(message['context_id'])
     context_uuid = message['context_id']['context_uuid']['uuid']
-    assert 'service_ids' in message
-    assert isinstance(message['service_ids'], list)
-    for service_id in message['service_ids']: validate_service_id(service_id, context_uuid=context_uuid)
+    assert 'name' in message
+    assert isinstance(message['name'], str)
     assert 'topology_ids' in message
     assert isinstance(message['topology_ids'], list)
     for topology_id in message['topology_ids']: validate_topology_id(topology_id, context_uuid=context_uuid)
+    assert 'service_ids' in message
+    assert isinstance(message['service_ids'], list)
+    for service_id in message['service_ids']: validate_service_id(service_id, context_uuid=context_uuid)
+    assert 'slice_ids' in message
+    assert isinstance(message['slice_ids'], list)
+    for slice_id in message['slice_ids']: validate_slice_id(slice_id, context_uuid=context_uuid)
 
 def validate_service_state(message):
     assert isinstance(message, dict)
@@ -261,11 +339,19 @@ def validate_service_state(message):
     assert 'service_status' in message
     validate_service_state_enum(message['service_status'])
 
+def validate_slice_status(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'slice_status' in message
+    validate_slice_status_enum(message['slice_status'])
+
 def validate_service(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 6
+    assert len(message.keys()) == 7
     assert 'service_id' in message
     validate_service_id(message['service_id'])
+    assert 'name' in message
+    assert isinstance(message['name'], str)
     assert 'service_type' in message
     validate_service_type_enum(message['service_type'])
     assert 'service_endpoint_ids' in message
@@ -279,11 +365,44 @@ def validate_service(message):
     assert 'service_config' in message
     validate_config_rules(message['service_config'])
 
+def validate_slice(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) in {8, 9}
+    assert 'slice_id' in message
+    validate_slice_id(message['slice_id'])
+    assert 'name' in message
+    assert isinstance(message['name'], str)
+    assert 'slice_endpoint_ids' in message
+    assert isinstance(message['slice_endpoint_ids'], list)
+    for endpoint_id in message['slice_endpoint_ids']: validate_endpoint_id(endpoint_id)
+    assert 'slice_constraints' in message
+    assert isinstance(message['slice_constraints'], list)
+    for constraint in message['slice_constraints']: validate_constraint(constraint)
+    assert 'slice_service_ids' in message
+    assert isinstance(message['slice_service_ids'], list)
+    for service_id in message['slice_service_ids']: validate_service_id(service_id)
+    assert 'slice_subslice_ids' in message
+    assert isinstance(message['slice_subslice_ids'], list)
+    for slice_id in message['slice_subslice_ids']: validate_slice_id(slice_id)
+    assert 'slice_status' in message
+    validate_slice_status(message['slice_status'])
+    assert 'slice_config' in message
+    validate_config_rules(message['slice_config'])
+    if len(message.keys()) == 9:
+        assert 'slice_owner' in message
+        assert isinstance(message['slice_owner'], dict)
+        assert 'owner_uuid' in message['slice_owner']
+        validate_uuid(message['slice_owner']['owner_uuid'])
+        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):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 3
+    assert len(message.keys()) == 4
     assert 'topology_id' in message
     validate_topology_id(message['topology_id'])
+    assert 'name' in message
+    assert isinstance(message['name'], str)
     assert 'device_ids' in message
     assert isinstance(message['device_ids'], list)
     if num_devices is not None: assert len(message['device_ids']) == num_devices
@@ -295,20 +414,49 @@ def validate_topology(message, num_devices=None, num_links=None):
 
 def validate_endpoint(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 3
+    assert len(message.keys()) == 4
     assert 'endpoint_id' in message
     validate_endpoint_id(message['endpoint_id'])
+    assert 'name' in message
+    assert isinstance(message['name'], str)
     assert 'endpoint_type' in message
     assert isinstance(message['endpoint_type'], str)
     assert 'kpi_sample_types' in message
     assert isinstance(message['kpi_sample_types'], list)
     for kpi_sample_type in message['kpi_sample_types']: validate_kpi_sample_types_enum(kpi_sample_type)
 
+def validate_component(component):
+    assert isinstance(component, dict)
+    assert len(component.keys()) == 5
+    assert 'component_uuid' in component
+    validate_uuid(component['component_uuid'])
+    assert 'name' in component
+    assert isinstance(component['name'], str)
+    assert 'type' in component
+    assert isinstance(component['type'], str)
+    assert 'attributes' in component
+    assert isinstance(component['attributes'], dict)
+    for k,v in component['attributes'].items():
+        assert isinstance(k, str)
+        assert isinstance(v, str)
+    assert 'parent' in component
+    assert isinstance(component['parent'], str)
+
+def validate_link_attributes(link_attributes):
+    assert isinstance(link_attributes, dict)
+    assert len(link_attributes.keys()) == 2
+    assert 'total_capacity_gbps' in link_attributes
+    assert isinstance(link_attributes['total_capacity_gbps'], (int, float))
+    assert 'used_capacity_gbps' in link_attributes
+    assert isinstance(link_attributes['used_capacity_gbps'], (int, float))
+
 def validate_device(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 6
+    assert len(message.keys()) in {8, 9}
     assert 'device_id' in message
     validate_device_id(message['device_id'])
+    assert 'name' in message
+    assert isinstance(message['name'], str)
     assert 'device_type' in message
     assert isinstance(message['device_type'], str)
     assert 'device_config' in message
@@ -321,19 +469,30 @@ def validate_device(message):
     assert 'device_endpoints' in message
     assert isinstance(message['device_endpoints'], list)
     for endpoint in message['device_endpoints']: validate_endpoint(endpoint)
+    assert 'components' in message
+    assert isinstance(message['components'], list)
+    for component in message['components']: validate_component(component)
+    if len(message.keys()) == 9:
+        assert 'controller_id' in message
+        if len(message['controller_id']) > 0:
+            validate_device_id(message['controller_id'])
 
 def validate_link(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 2
+    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 'attributes' in message
+    validate_link_attributes(message['attributes'])
 
 def validate_connection(message):
     assert isinstance(message, dict)
-    assert len(message.keys()) == 4
+    assert len(message.keys()) in {4, 5}
     assert 'connection_id' in message
     validate_connection_id(message['connection_id'])
     assert 'service_id' in message
@@ -344,6 +503,50 @@ def validate_connection(message):
     assert 'sub_service_ids' in message
     assert isinstance(message['sub_service_ids'], list)
     for sub_service_id in message['sub_service_ids']: validate_service_id(sub_service_id)
+    if len(message.keys()) == 5:
+        assert 'settings' in message
+        assert isinstance(message['settings'], dict)
+        # TODO: improve validation of data types, especially for uint values, IP/MAC addresses, TCP/UDP ports, etc.
+        if 'l0' in message['settings']:
+            assert isinstance(message['settings']['l0'], dict)
+            if 'lsp_symbolic_name' in message['settings']['l0']:
+                assert isinstance(message['settings']['l0']['lsp_symbolic_name'], str)
+        if 'l2' in message['settings']:
+            assert isinstance(message['settings']['l2'], dict)
+            if 'src_mac_address' in message['settings']['l2']:
+                assert isinstance(message['settings']['l2']['src_mac_address'], str)
+            if 'dst_mac_address' in message['settings']['l2']:
+                assert isinstance(message['settings']['l2']['dst_mac_address'], str)
+            if 'ether_type' in message['settings']['l2']:
+                assert isinstance(message['settings']['l2']['ether_type'], int)
+            if 'vlan_id' in message['settings']['l2']:
+                assert isinstance(message['settings']['l2']['vlan_id'], int)
+            if 'mpls_label' in message['settings']['l2']:
+                assert isinstance(message['settings']['l2']['mpls_label'], int)
+            if 'mpls_traffic_class' in message['settings']['l2']:
+                assert isinstance(message['settings']['l2']['mpls_traffic_class'], int)
+        if 'l3' in message['settings']:
+            assert isinstance(message['settings']['l3'], dict)
+            if 'src_ip_address' in message['settings']['l3']:
+                assert isinstance(message['settings']['l3']['src_ip_address'], str)
+            if 'dst_ip_address' in message['settings']['l3']:
+                assert isinstance(message['settings']['l3']['dst_ip_address'], str)
+            if 'dscp' in message['settings']['l3']:
+                assert isinstance(message['settings']['l3']['dscp'], int)
+            if 'protocol' in message['settings']['l3']:
+                assert isinstance(message['settings']['l3']['protocol'], int)
+            if 'ttl' in message['settings']['l3']:
+                assert isinstance(message['settings']['l3']['ttl'], int)
+        if 'l4' in message['settings']:
+            assert isinstance(message['settings']['l4'], dict)
+            if 'src_port' in message['settings']['l4']:
+                assert isinstance(message['settings']['l4']['src_port'], int)
+            if 'dst_port' in message['settings']['l4']:
+                assert isinstance(message['settings']['l4']['dst_port'], int)
+            if 'tcp_flags' in message['settings']['l4']:
+                assert isinstance(message['settings']['l4']['tcp_flags'], int)
+            if 'ttl' in message['settings']['l4']:
+                assert isinstance(message['settings']['l4']['ttl'], int)
 
 
 # ----- Lists of Objects -----------------------------------------------------------------------------------------------
@@ -362,6 +565,13 @@ def validate_services(message):
     assert isinstance(message['services'], list)
     for service in message['services']: validate_service(service)
 
+def validate_slices(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'slices' in message
+    assert isinstance(message['slices'], list)
+    for slice_ in message['slices']: validate_slice(slice_)
+
 def validate_topologies(message):
     assert isinstance(message, dict)
     assert len(message.keys()) == 1
diff --git a/src/nbi/.gitlab-ci.yml b/src/nbi/.gitlab-ci.yml
index d9d790803a5cb0387d2d3447ef700154879bb615..e0cac446a33b36a4fbe65b3da1ad5767582a77c6 100644
--- a/src/nbi/.gitlab-ci.yml
+++ b/src/nbi/.gitlab-ci.yml
@@ -66,6 +66,7 @@ unit_test nbi:
     - sleep 5
     - docker ps -a
     - docker logs $IMAGE_NAME
+    - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_debug_api.py --junitxml=/opt/results/${IMAGE_NAME}_report_debug_api.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_ietf_l2vpn.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_l2vpn.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_ietf_network.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_network.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_ietf_l3vpn.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_l3vpn.xml"
diff --git a/src/nbi/tests/data/debug_api_dummy.json b/src/nbi/tests/data/debug_api_dummy.json
new file mode 100644
index 0000000000000000000000000000000000000000..d8f5137578629408556e3758c512f137fc633d6c
--- /dev/null
+++ b/src/nbi/tests/data/debug_api_dummy.json
@@ -0,0 +1,442 @@
+{
+    "dummy_mode": true,
+    "contexts": [
+        {
+            "context_id": {"context_uuid": {"uuid": "admin"}},
+            "name": "admin",
+            "topology_ids": [
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+            ],
+            "service_ids": [
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R2/200"}},
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R3/200"}},
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R2/200==R3/200"}}
+            ],
+            "slice_ids": [
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "slice_uuid": {"uuid": "SLC:R1-R2-R3"}}
+            ]
+        }
+    ],
+    "topologies": [
+        {
+            "device_ids": [
+                {"device_uuid": {"uuid": "R1"}},
+                {"device_uuid": {"uuid": "R2"}},
+                {"device_uuid": {"uuid": "R3"}}
+            ],
+            "link_ids": [
+                {"link_uuid": {"uuid": "R1/502==R2/501"}},
+                {"link_uuid": {"uuid": "R1/503==R3/501"}},
+                {"link_uuid": {"uuid": "R2/501==R1/502"}},
+                {"link_uuid": {"uuid": "R2/503==R3/502"}},
+                {"link_uuid": {"uuid": "R3/501==R1/503"}},
+                {"link_uuid": {"uuid": "R3/502==R2/503"}}
+            ],
+            "name": "admin",
+            "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+        }
+    ],
+    "devices": [
+        {
+            "device_id": {"device_uuid": {"uuid": "R1"}}, "name": "R1", "device_type": "emu-packet-router",
+            "device_drivers": [0], "device_operational_status": 2,
+            "device_endpoints": [
+                {"name": "200", "endpoint_type": "copper", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"name": "502", "endpoint_type": "optical", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"name": "503", "endpoint_type": "optical", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": 0}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
+                    {"uuid": "200", "name": "200", "type": "copper"},
+                    {"uuid": "502", "name": "502", "type": "optical"},
+                    {"uuid": "503", "name": "503", "type": "optical"}
+                ]}}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[200]", "resource_value": {
+                    "uuid": "200", "name": "200", "type": "copper"
+                }}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[502]", "resource_value": {
+                    "uuid": "502", "name": "502", "type": "optical"
+                }}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[503]", "resource_value": {
+                    "uuid": "503", "name": "503", "type": "optical"
+                }}}
+            ]}
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R2"}}, "name": "R2", "device_type": "emu-packet-router",
+            "device_drivers": [0], "device_operational_status": 2,
+            "device_endpoints": [
+                {"name": "200", "endpoint_type": "copper", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"name": "501", "endpoint_type": "optical", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"name": "503", "endpoint_type": "optical", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": 0}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
+                    {"uuid": "200", "name": "200", "type": "copper"},
+                    {"uuid": "501", "name": "501", "type": "optical"},
+                    {"uuid": "503", "name": "503", "type": "optical"}
+                ]}}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[200]", "resource_value": {
+                    "uuid": "200", "name": "200", "type": "copper"
+                }}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[501]", "resource_value": {
+                    "uuid": "501", "name": "501", "type": "optical"
+                }}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[503]", "resource_value": {
+                    "uuid": "503", "name": "503", "type": "optical"
+                }}}
+            ]}
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R3"}}, "name": "R3", "device_type": "emu-packet-router",
+            "device_drivers": [0], "device_operational_status": 2,
+            "device_endpoints": [
+                {"name": "200", "endpoint_type": "copper", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"name": "502", "endpoint_type": "optical", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"name": "503", "endpoint_type": "optical", "endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": 0}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
+                    {"uuid": "200", "name": "200", "type": "copper"},
+                    {"uuid": "502", "name": "502", "type": "optical"},
+                    {"uuid": "503", "name": "503", "type": "optical"}
+                ]}}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[200]", "resource_value": {
+                    "uuid": "200", "name": "200", "type": "copper"
+                }}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[502]", "resource_value": {
+                    "uuid": "502", "name": "502", "type": "optical"
+                }}},
+                {"action": 1, "custom": {"resource_key": "/endpoints/endpoint[503]", "resource_value": {
+                    "uuid": "503", "name": "503", "type": "optical"
+                }}}
+            ]}
+        }
+    ],
+    "links": [
+        {
+            "link_id": {"link_uuid": {"uuid": "R1/502==R2/501"}}, "name": "R1/502==R2/501",
+            "attributes": {"total_capacity_gbps": 10.0, "used_capacity_gbps": 0.0},
+            "link_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R1/503==R3/501"}}, "name": "R1/503==R3/501",
+            "attributes": {"total_capacity_gbps": 10.0, "used_capacity_gbps": 0.0},
+            "link_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R2/501==R1/502"}}, "name": "R2/501==R1/502",
+            "attributes": {"total_capacity_gbps": 10.0, "used_capacity_gbps": 0.0},
+            "link_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R2/503==R3/502"}}, "name": "R2/503==R3/502",
+            "attributes": {"total_capacity_gbps": 10.0, "used_capacity_gbps": 0.0},
+            "link_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R3/501==R1/503"}}, "name": "R3/501==R1/503",
+            "attributes": {"total_capacity_gbps": 10.0, "used_capacity_gbps": 0.0},
+            "link_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R3/502==R2/503"}}, "name": "R3/502==R2/503",
+            "attributes": {"total_capacity_gbps": 10.0, "used_capacity_gbps": 0.0},
+            "link_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ]
+        }
+    ],
+    "services": [
+        {
+            "service_id" : {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R2/200"}},
+            "name": "SVC:R1/200==R2/200", "service_type": 1, "service_status": {"service_status": 1},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "service_constraints": [
+                {"action": 1, "sla_capacity": {"capacity_gbps": 40.0}},
+                {"action": 1, "sla_latency": {"e2e_latency_ms": 10.0}},
+                {"action": 1, "sla_availability": {"num_disjoint_paths": 1, "all_active": true, "availability": 99.99}}
+            ],
+            "service_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "/device[R1]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.1.1", "ipv4_prefix": 24
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R2]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.2.1", "ipv4_prefix": 24
+                }}}
+            ]}
+        },
+        {
+            "service_id" : {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R3/200"}},
+            "name": "SVC:R1/200==R3/200", "service_type": 1, "service_status": {"service_status": 1},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "service_constraints": [
+                {"action": 1, "sla_capacity": {"capacity_gbps": 50.0}},
+                {"action": 1, "sla_latency": {"e2e_latency_ms": 8.0}},
+                {"action": 1, "sla_availability": {"num_disjoint_paths": 1, "all_active": true, "availability": 99.9}}
+            ],
+            "service_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "/device[R1]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.1.1", "ipv4_prefix": 24
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R3]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.3.1", "ipv4_prefix": 24
+                }}}
+            ]}
+        },
+        {
+            "service_id" : {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R2/200==R3/200"}},
+            "name": "SVC:R2/200==R3/200", "service_type": 1, "service_status": {"service_status": 1},
+            "service_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "service_constraints": [
+                {"action": 1, "sla_capacity": {"capacity_gbps": 10.0}},
+                {"action": 1, "sla_latency": {"e2e_latency_ms": 3.0}},
+                {"action": 1, "sla_availability": {"num_disjoint_paths": 1, "all_active": true, "availability": 99.9999}}
+            ],
+            "service_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "/device[R2]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.2.1", "ipv4_prefix": 24
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R3]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.3.1", "ipv4_prefix": 24
+                }}}
+            ]}
+        }
+    ],
+    "slices": [
+        {
+            "slice_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "slice_uuid": {"uuid": "SLC:R1-R2-R3"}},
+            "name": "SLC:R1-R2-R3",
+            "slice_endpoint_ids": [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "slice_constraints": [
+                {"action": 1, "sla_capacity": {"capacity_gbps": 40.0}},
+                {"action": 1, "sla_latency": {"e2e_latency_ms": 10.0}},
+                {"action": 1, "sla_availability": {"num_disjoint_paths": 1, "all_active": true, "availability": 99.99}}
+            ],
+            "slice_service_ids": [
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R2/200"}},
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R3/200"}},
+                {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R2/200==R3/200"}}
+            ],
+            "slice_subslice_ids": [],
+            "slice_status": {"slice_status" : 1},
+            "slice_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "/device[R1]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.1.1", "ipv4_prefix": 24
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R2]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.2.1", "ipv4_prefix": 24
+                }}},
+                {"action": 1, "custom": {"resource_key": "/device[R3]/endpoint[200]/settings", "resource_value": {
+                    "ipv4_address": "10.0.3.1", "ipv4_prefix": 24
+                }}}
+            ]},
+            "slice_owner": {"owner_uuid": {"uuid": "TFS"}, "owner_string": "TFS:SLC:R1-R2-R3"}
+        }
+    ],
+    "connections": [
+        {
+            "connection_id": {"connection_uuid": {"uuid": "CON:R1/200==R2/200:1"}},
+            "service_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R2/200"}},
+            "path_hops_endpoint_ids" : [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "sub_service_ids": [],
+            "settings": {
+                "l3": {"src_ip_address": "10.0.1.10", "dst_ip_address": "10.0.2.10", "ttl": 20}
+            }
+        },
+        {
+            "connection_id": {"connection_uuid": {"uuid": "CON:R1/200==R3/200:1"}},
+            "service_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R1/200==R3/200"}},
+            "path_hops_endpoint_ids" : [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "501"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "sub_service_ids": [],
+            "settings": {
+                "l3": {"src_ip_address": "10.0.1.10", "dst_ip_address": "10.0.3.10", "ttl": 20}
+            }
+        },
+        {
+            "connection_id": {"connection_uuid": {"uuid": "CON:R2/200==R3/200:1"}},
+            "service_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "SVC:R2/200==R3/200"}},
+            "path_hops_endpoint_ids" : [
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "503"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "502"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                },
+                {
+                    "device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "200"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }
+            ],
+            "sub_service_ids": [],
+            "settings": {
+                "l3": {"src_ip_address": "10.0.2.10", "dst_ip_address": "10.0.3.10", "ttl": 20}
+            }
+        }
+    ]
+}
diff --git a/src/nbi/tests/test_debug_api.py b/src/nbi/tests/test_debug_api.py
index e284992618a96388371b69b7b0c2a8c4fcaaba70..f19531eaed3b106279c2752a55eb00bb1ca30bb7 100644
--- a/src/nbi/tests/test_debug_api.py
+++ b/src/nbi/tests/test_debug_api.py
@@ -12,209 +12,206 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging, os, pytest, time, urllib
-from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, ServiceNameEnum
-from common.proto.context_pb2 import Connection, Context, Device, Link, Service, Slice, Topology
-from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule
-from common.Settings import (
-    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, ENVVAR_SUFIX_SERVICE_PORT_HTTP, get_env_var_name,
-    get_service_port_grpc, get_service_port_http
+import logging, urllib
+from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME
+from common.proto.context_pb2 import ContextId
+from common.tools.descriptor.Loader import (
+    DescriptorLoader, check_descriptor_load_results, validate_empty_scenario
 )
+from common.tools.object_factory.Context import json_context_id
 from common.type_checkers.Assertions import (
-    validate_connection, validate_connection_ids, validate_connections, validate_context, validate_context_ids,
-    validate_contexts, validate_device, validate_device_ids, validate_devices, validate_link, validate_link_ids,
-    validate_links, validate_service, validate_service_ids, validate_services, validate_topologies, validate_topology,
-    validate_topology_ids)
+    validate_connection, validate_connection_ids, validate_connections,
+    validate_context, validate_context_ids, validate_contexts,
+    validate_device, validate_device_ids, validate_devices,
+    validate_link, validate_link_ids, validate_links,
+    validate_service, validate_service_ids, validate_services,
+    validate_slice, validate_slice_ids, validate_slices,
+    validate_topologies, validate_topology, validate_topology_ids
+)
 from context.client.ContextClient import ContextClient
-from nbi.tests.PrepareTestScenario import do_rest_get_request
-from .MockService_Dependencies import MockService_Dependencies
-from .Objects import (
-    CONNECTION_R1_R3, CONNECTION_R1_R3_ID, CONNECTION_R1_R3_UUID, CONTEXT, CONTEXT_ID, DEVICE_R1, DEVICE_R1_ID,
-    DEVICE_R1_UUID, DEVICE_R2, DEVICE_R2_ID, DEVICE_R2_UUID, DEVICE_R3, DEVICE_R3_ID, DEVICE_R3_UUID, LINK_R1_R2,
-    LINK_R1_R2_ID, LINK_R1_R2_UUID, SERVICE_R1_R2, SERVICE_R1_R2_ID, SERVICE_R1_R2_UUID, SERVICE_R1_R3,
-    SERVICE_R1_R3_ID, SERVICE_R1_R3_UUID, SERVICE_R2_R3, SERVICE_R2_R3_ID, SERVICE_R2_R3_UUID, SLICE_R1_R3, TOPOLOGY,
-    TOPOLOGY_ID, POLICY_RULE, POLICY_RULE_ID, POLICY_RULE_UUID
+from nbi.service.rest_server.RestServer import RestServer
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, nbi_service_rest, context_client,
+    do_rest_get_request
 )
 
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = 'nbi/tests/data/debug_api_dummy.json'
 
-@pytest.fixture(scope='session')
-def mock_service():
-    _service = MockService_Dependencies(MOCKSERVICE_PORT)
-    _service.configure_env_vars()
-    _service.start()
-    yield _service
-    _service.stop()
+JSON_ADMIN_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME)
+ADMIN_CONTEXT_ID = ContextId(**JSON_ADMIN_CONTEXT_ID)
 
 
+# ----- Prepare Environment --------------------------------------------------------------------------------------------
 
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
+def test_prepare_environment(context_client : ContextClient) -> None: # pylint: disable=redefined-outer-name
+    validate_empty_scenario(context_client)
+    descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client)
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+    descriptor_loader.validate()
 
-LOCAL_HOST = '127.0.0.1'
-GRPC_PORT = 10000 + int(get_service_port_grpc(ServiceNameEnum.CONTEXT))   # avoid privileged ports
-HTTP_PORT = 10000 + int(get_service_port_http(ServiceNameEnum.CONTEXT))   # avoid privileged ports
-
-MOCKSERVICE_PORT = 10000
-DEVICE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.DEVICE) # avoid privileged ports
-
-os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
-os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(GRPC_PORT)
-os.environ[get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_HTTP)] = str(HTTP_PORT)
-
-@pytest.fixture(scope='session')
-def context_service_grpc():
-    _service = ContextService(context_s_mb[0], context_s_mb[1])
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def context_service_rest():
-    database = context_db_mb[0]
-    _rest_server = RestServer()
-    for endpoint_name, resource_class, resource_url in RESOURCES:
-        _rest_server.add_resource(resource_class, resource_url, endpoint=endpoint_name, resource_class_args=(database,))
-    _rest_server.start()
-    time.sleep(1) # bring time for the server to start
-    yield _rest_server
-    _rest_server.shutdown()
-    _rest_server.join()
-
-@pytest.fixture(scope='session')
-def context_client_grpc(context_service_grpc : ContextService): # pylint: disable=redefined-outer-name
-    _client = ContextClient()
-    yield _client
-    _client.close()
-
-def test_populate_database():
-    client = ContextClient(host=LOCAL_HOST, port=GRPC_PORT)
-    client.SetContext(Context(**CONTEXT))
-    client.SetTopology(Topology(**TOPOLOGY))
-    client.SetDevice(Device(**DEVICE_R1))
-    client.SetDevice(Device(**DEVICE_R2))
-    client.SetDevice(Device(**DEVICE_R3))
-    client.SetLink(Link(**LINK_R1_R2))
-    client.SetLink(Link(**LINK_R1_R3))
-    client.SetLink(Link(**LINK_R2_R3))
-    client.SetService(Service(**SERVICE_R1_R2))
-    client.SetService(Service(**SERVICE_R1_R3))
-    client.SetService(Service(**SERVICE_R2_R3))
-    client.SetSlice(Slice(**SLICE_R1_R3))
-    client.SetConnection(Connection(**CONNECTION_R1_R3))
-
-def test_rest_get_context_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/context_ids')
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.topology_ids) == 1
+    assert len(response.service_ids ) == 3
+    assert len(response.slice_ids   ) == 1
+
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+
+def test_rest_get_context_ids(nbi_service_rest: RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    reply = do_rest_get_request('/debug-api/context_ids')
     validate_context_ids(reply)
 
-def test_rest_get_contexts(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/contexts')
+def test_rest_get_contexts(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    reply = do_rest_get_request('/debug-api/contexts')
     validate_contexts(reply)
 
-def test_rest_get_context(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_context(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}'.format(context_uuid))
+    reply = do_rest_get_request('/debug-api/context/{:s}'.format(context_uuid))
     validate_context(reply)
 
-def test_rest_get_topology_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+
+# ----- Topology -------------------------------------------------------------------------------------------------------
+
+def test_rest_get_topology_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}/topology_ids'.format(context_uuid))
+    reply = do_rest_get_request('/debug-api/context/{:s}/topology_ids'.format(context_uuid))
     validate_topology_ids(reply)
 
-def test_rest_get_topologies(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_topologies(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}/topologies'.format(context_uuid))
+    reply = do_rest_get_request('/debug-api/context/{:s}/topologies'.format(context_uuid))
     validate_topologies(reply)
 
-def test_rest_get_topology(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_topology(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
     topology_uuid = urllib.parse.quote(DEFAULT_TOPOLOGY_NAME)
-    reply = do_rest_get_request('/context/{:s}/topology/{:s}'.format(context_uuid, topology_uuid))
-    validate_topology(reply, num_devices=3, num_links=3)
+    reply = do_rest_get_request('/debug-api/context/{:s}/topology/{:s}'.format(context_uuid, topology_uuid))
+    validate_topology(reply, num_devices=3, num_links=6)
+
+
+# ----- Device ---------------------------------------------------------------------------------------------------------
+
+def test_rest_get_device_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    reply = do_rest_get_request('/debug-api/device_ids')
+    validate_device_ids(reply)
+
+def test_rest_get_devices(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    reply = do_rest_get_request('/debug-api/devices')
+    validate_devices(reply)
+
+def test_rest_get_device(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    device_uuid = urllib.parse.quote('R1', safe='')
+    reply = do_rest_get_request('/debug-api/device/{:s}'.format(device_uuid))
+    validate_device(reply)
+
+
+# ----- Link -----------------------------------------------------------------------------------------------------------
+
+def test_rest_get_link_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    reply = do_rest_get_request('/debug-api/link_ids')
+    validate_link_ids(reply)
 
-def test_rest_get_service_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_links(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    reply = do_rest_get_request('/debug-api/links')
+    validate_links(reply)
+
+def test_rest_get_link(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    link_uuid = urllib.parse.quote('R1/502==R2/501', safe='')
+    reply = do_rest_get_request('/debug-api/link/{:s}'.format(link_uuid))
+    validate_link(reply)
+
+
+# ----- Service --------------------------------------------------------------------------------------------------------
+
+def test_rest_get_service_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}/service_ids'.format(context_uuid))
+    reply = do_rest_get_request('/debug-api/context/{:s}/service_ids'.format(context_uuid))
     validate_service_ids(reply)
 
-def test_rest_get_services(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_services(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}/services'.format(context_uuid))
+    reply = do_rest_get_request('/debug-api/context/{:s}/services'.format(context_uuid))
     validate_services(reply)
 
-def test_rest_get_service(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_service(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    service_uuid = urllib.parse.quote(SERVICE_R1_R2_UUID, safe='')
-    reply = do_rest_get_request('/context/{:s}/service/{:s}'.format(context_uuid, service_uuid))
+    service_uuid = urllib.parse.quote('SVC:R1/200==R2/200', safe='')
+    reply = do_rest_get_request('/debug-api/context/{:s}/service/{:s}'.format(context_uuid, service_uuid))
     validate_service(reply)
 
-def test_rest_get_slice_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}/slice_ids'.format(context_uuid))
-    #validate_slice_ids(reply)
 
-def test_rest_get_slices(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    reply = do_rest_get_request('/context/{:s}/slices'.format(context_uuid))
-    #validate_slices(reply)
+# ----- Slice ----------------------------------------------------------------------------------------------------------
 
-def test_rest_get_slice(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_slice_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    slice_uuid = urllib.parse.quote(SLICE_R1_R3_UUID, safe='')
-    reply = do_rest_get_request('/context/{:s}/slice/{:s}'.format(context_uuid, slice_uuid))
-    #validate_slice(reply)
-
-def test_rest_get_device_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/device_ids')
-    validate_device_ids(reply)
-
-def test_rest_get_devices(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/devices')
-    validate_devices(reply)
+    reply = do_rest_get_request('/debug-api/context/{:s}/slice_ids'.format(context_uuid))
+    validate_slice_ids(reply)
 
-def test_rest_get_device(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    device_uuid = urllib.parse.quote(DEVICE_R1_UUID, safe='')
-    reply = do_rest_get_request('/device/{:s}'.format(device_uuid))
-    validate_device(reply)
+def test_rest_get_slices(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
+    reply = do_rest_get_request('/debug-api/context/{:s}/slices'.format(context_uuid))
+    validate_slices(reply)
 
-def test_rest_get_link_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/link_ids')
-    validate_link_ids(reply)
+def test_rest_get_slice(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
+    slice_uuid = urllib.parse.quote('SLC:R1-R2-R3', safe='')
+    reply = do_rest_get_request('/debug-api/context/{:s}/slice/{:s}'.format(context_uuid, slice_uuid))
+    validate_slice(reply)
 
-def test_rest_get_links(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/links')
-    validate_links(reply)
 
-def test_rest_get_link(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    link_uuid = urllib.parse.quote(LINK_R1_R2_UUID, safe='')
-    reply = do_rest_get_request('/link/{:s}'.format(link_uuid))
-    validate_link(reply)
+# ----- Connection -----------------------------------------------------------------------------------------------------
 
-def test_rest_get_connection_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_connection_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    service_uuid = urllib.parse.quote(SERVICE_R1_R3_UUID, safe='')
-    reply = do_rest_get_request('/context/{:s}/service/{:s}/connection_ids'.format(context_uuid, service_uuid))
+    service_uuid = urllib.parse.quote('SVC:R1/200==R2/200', safe='')
+    reply = do_rest_get_request('/debug-api/context/{:s}/service/{:s}/connection_ids'.format(context_uuid, service_uuid))
     validate_connection_ids(reply)
 
-def test_rest_get_connections(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+def test_rest_get_connections(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
     context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_NAME)
-    service_uuid = urllib.parse.quote(SERVICE_R1_R3_UUID, safe='')
-    reply = do_rest_get_request('/context/{:s}/service/{:s}/connections'.format(context_uuid, service_uuid))
+    service_uuid = urllib.parse.quote('SVC:R1/200==R2/200', safe='')
+    reply = do_rest_get_request('/debug-api/context/{:s}/service/{:s}/connections'.format(context_uuid, service_uuid))
     validate_connections(reply)
 
-def test_rest_get_connection(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    connection_uuid = urllib.parse.quote(CONNECTION_R1_R3_UUID, safe='')
-    reply = do_rest_get_request('/connection/{:s}'.format(connection_uuid))
+def test_rest_get_connection(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+    connection_uuid = urllib.parse.quote('CON:R1/200==R2/200:1', safe='')
+    reply = do_rest_get_request('/debug-api/connection/{:s}'.format(connection_uuid))
     validate_connection(reply)
 
-def test_rest_get_policyrule_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/policyrule_ids')
-    #validate_policyrule_ids(reply)
+# ----- Policy ---------------------------------------------------------------------------------------------------------
+
+#def test_rest_get_policyrule_ids(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+#    reply = do_rest_get_request('/debug-api/policyrule_ids')
+#    validate_policyrule_ids(reply)
+
+#def test_rest_get_policyrules(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+#    reply = do_rest_get_request('/debug-api/policyrules')
+#    validate_policyrules(reply)
+
+#def test_rest_get_policyrule(nbi_service_rest : RestServer): # pylint: disable=redefined-outer-name, unused-argument
+#    policyrule_uuid_quoted = urllib.parse.quote(policyrule_uuid, safe='')
+#    reply = do_rest_get_request('/debug-api/policyrule/{:s}'.format(policyrule_uuid_quoted))
+#    validate_policyrule(reply)
+
+
+# ----- Cleanup Environment --------------------------------------------------------------------------------------------
 
-def test_rest_get_policyrules(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    reply = do_rest_get_request('/policyrules')
-    #validate_policyrules(reply)
+def test_cleanup_environment(context_client : ContextClient) -> None: # pylint: disable=redefined-outer-name
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.topology_ids) == 1
+    assert len(response.service_ids ) == 3
+    assert len(response.slice_ids   ) == 1
 
-def test_rest_get_policyrule(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
-    policyrule_uuid = urllib.parse.quote(POLICYRULE_UUID, safe='')
-    reply = do_rest_get_request('/policyrule/{:s}'.format(policyrule_uuid))
-    #validate_policyrule(reply)
+    # Load descriptors and validate the base scenario
+    descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client)
+    descriptor_loader.validate()
+    descriptor_loader.unload()
+    validate_empty_scenario(context_client)
diff --git a/src/nbi/tests/test_ietf_l3vpn.py b/src/nbi/tests/test_ietf_l3vpn.py
index 17f3c3e93c627c41ddc344e55b3478d13077efb3..da9efdffd4dd6f4b3af956988aa3d51d3e855c84 100644
--- a/src/nbi/tests/test_ietf_l3vpn.py
+++ b/src/nbi/tests/test_ietf_l3vpn.py
@@ -21,7 +21,7 @@ from common.tools.descriptor.Loader import (
 )
 from common.tools.object_factory.Context import json_context_id
 from context.client.ContextClient import ContextClient
-from nbi.service.rest_server import RestServer
+from nbi.service.rest_server.RestServer import RestServer
 from .PrepareTestScenario import ( # pylint: disable=unused-import
     # be careful, order of symbols is important here!
     do_rest_delete_request, do_rest_get_request, do_rest_post_request,
diff --git a/src/webui/requirements.in b/src/webui/requirements.in
index 9facefbbae3c20b90304803e9ccfa4ebf4011fbb..2c638a223c6b45eecaf7479bdf249954e6bc8543 100644
--- a/src/webui/requirements.in
+++ b/src/webui/requirements.in
@@ -17,4 +17,4 @@ Flask-WTF==1.0.0
 flask-healthz==0.0.3
 flask-unittest==0.1.2
 lorem-text==2.1
-werkzeug==2.3.7
\ No newline at end of file
+werkzeug==2.3.7
diff --git a/src/webui/service/__init__.py b/src/webui/service/__init__.py
index 3c64f45c90457e1b6a9553e60634879a28910a31..05b2eeaf0b7277b960259950ec099b9517124c17 100644
--- a/src/webui/service/__init__.py
+++ b/src/webui/service/__init__.py
@@ -16,6 +16,7 @@ import json
 from typing import List, Tuple, Union
 from flask import Flask, request, session
 from flask_healthz import healthz, HealthError
+from common.tools.grpc.Tools import grpc_message_to_json
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 
@@ -100,6 +101,7 @@ def create_app(use_config=None, web_app_root=None):
 
     app.jinja_env.globals.update({              # pylint: disable=no-member
         'enumerate'           : enumerate,
+        'grpc_message_to_json': grpc_message_to_json,
         'json_to_list'        : json_to_list,
         'round'               : round,
         'get_working_context' : get_working_context,
diff --git a/src/webui/service/service/forms.py b/src/webui/service/service/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..b3fffcc89a6256e367690032c66530e188e00a8d
--- /dev/null
+++ b/src/webui/service/service/forms.py
@@ -0,0 +1,261 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import ipaddress, re
+from flask_wtf import FlaskForm
+from wtforms import StringField, SelectField, IntegerField, DecimalField
+from wtforms.validators import InputRequired, Optional, NumberRange, ValidationError, StopValidation
+
+# Custom IPv4 address validator
+def validate_ipv4_address(form, field):
+    try:
+        ipaddress.IPv4Address(field.data)
+    except ipaddress.AddressValueError:
+        raise ValidationError('Invalid IPv4 address format')
+
+# Custom IPv6 address validator
+def validate_ipv6_address(form, field):
+    try:
+        ipaddress.IPv6Address(field.data)
+    except ipaddress.AddressValueError:
+        raise ValidationError('Invalid IPv6 address format')
+    
+# Custom Mac address validator
+def validate_mac_address(form, field):             
+    if not re.match(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$', field.data):
+        raise ValidationError('Invalid MAC address format')
+
+# Custom route distinguisher validator
+def validate_route_distinguisher(form,field):
+    pattern = r'^([0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]):([0-9]|[1-9][0-9]{1,8}|[1-3][0-9]{9}|4[01][0-9]{8}|42[0-8][0-9]{7}|429[0-3][0-9]{6}|4294[0-8][0-9]{5}|42949[0-5][0-9]{4}|429496[0-6][0-9]{3}|4294967[01][0-9]{2}|42949672[0-8][0-9]|429496729[0-5])$'
+    if not re.match(pattern, field.data):
+        raise ValidationError('Invalid Route Distinguisher')
+
+# Custom integer validator
+def validate_uint32(form, field):
+    if not 0 <= field.data <= 2**32-1:
+        raise ValidationError('Value must be a positive integer within the range of uint32')
+
+# Custom  BGP AS validator
+def validate_NI_as(form, field):
+    if form.NI_protocol.data == 'BGP' and field.data == None:
+        raise StopValidation('AS field is required if the BGP protocol is selected.')
+        
+class CustomInputRequired():
+    def __init__(self, message=None):
+        self.message = message or "This field is required." 
+    def __call__(self, form, field):
+        if field.data is None or field.data == '':
+            raise StopValidation(self.message)
+        
+class AddServiceForm_1(FlaskForm):
+    service_type = SelectField('Type of service', choices=[('', 'Select a type of service to add'), ('ACL_L2', 'ACL_L2'), ('ACL_IPV4', 'ACL_IPV4'), ('ACL_IPV6', 'ACL_IPV6'), ('L2VPN', 'L2VPN'), ('L3VPN', 'L3VPN')], validators=[InputRequired()])
+
+class AddServiceForm_ACL_L2(FlaskForm):
+    #GENERIC SERVICE PARAMETERS (COMMON & MANDATORY)
+    service_name       = StringField('Service Name', validators=[CustomInputRequired()])
+    service_type       = SelectField('Service Type', choices=[(2, '2 (L2NM)')], validators=[CustomInputRequired()])
+    service_device_1   = SelectField('Device_1', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_device_2   = SelectField('Device_2', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_endpoint_1 = StringField('Device_1 Endpoint', validators=[CustomInputRequired()])
+    service_endpoint_2 = StringField('Device_2 Endpoint', validators=[CustomInputRequired()])
+    
+    #GENERIC SERVICE CONSTRAINT PARAMETERS (ALL OPTIONAL)
+    service_capacity    = DecimalField('Service Capacity', places=2, default=10.00, validators=[Optional(), NumberRange(min=0)])
+    service_latency     = DecimalField('Service Latency', places=2, default=15.20, validators=[Optional(), NumberRange(min=0)])
+    service_availability= DecimalField('Service Availability', places=2, validators=[Optional(), NumberRange(min=0)])
+    service_isolation   = SelectField('Service Isolation', choices=[('', 'Select (Optional)'), ('NO_ISOLATION', 'NO_ISOLATION'), ('PHYSICAL_ISOLATION', 'PHYSICAL_ISOLATION'), 
+                                                                    ('LOGICAL_ISOLATION', 'LOGICAL_ISOLATION'), ('PROCESS_ISOLATION', 'PROCESS_ISOLATION'), ('PHYSICAL_MEMORY_ISOLATION', 'PHYSICAL_MEMORY_ISOLATION'), 
+                                                                    ('PHYSICAL_NETWORK_ISOLATION', 'PHYSICAL_NETWORK_ISOLATION'), ('VIRTUAL_RESOURCE_ISOLATION', 'VIRTUAL_RESOURCE_ISOLATION'), 
+                                                                    ('NETWORK_FUNCTIONS_ISOLATION', 'NETWORK_FUNCTIONS_ISOLATION'), ('SERVICE_ISOLATION', 'SERVICE_ISOLATION')], validators=[Optional()])
+    
+    #MANDATORY_PARAMETERS
+    name                = StringField('ACL Name', validators=[CustomInputRequired("The name of the ACL is a mandatory parameter")])
+    type                = SelectField('ACL Type', choices=[('ACL_L2', 'ACL_L2')], validators=[CustomInputRequired("The type of the ACL is a mandatory parameter")])
+    sequence_id         = IntegerField('ACL Sequence ID', validators=[CustomInputRequired("The name of the Sequence ID of the ACL is a mandatory parameter"), validate_uint32])
+    forwarding_action   = SelectField('ACL Fowarding Action', choices=[('', 'Select an action (Mandatory)'), ('ACCEPT', 'Accept'), ('DROP','Drop'),('REJECT','Reject')], validators=[CustomInputRequired("The Forwarding Action of the ACL is a mandatory parameter")])  
+    log_action          = SelectField('ACL Log Action', choices=[(None, 'Select a log action (Optional)'), ('LOG_SYSLOG', 'Syslog'), ('LOG_NONE','None')], validators=[Optional()]) 
+
+    #PARAMETERS FOR Associating ACL to IF 
+    interface           = StringField('Interface Name', validators=[CustomInputRequired("The name of the Interface is a mandatory parameter")])
+    subinterface        = StringField('Subinterface Index', validators=[Optional()])
+    traffic_flow        = SelectField('ACL Traffic Flow Direction', choices=[('', 'Select a direction (Mandatory)'), ('Ingress', 'Ingress'), ('Egress','Egress')], validators=[CustomInputRequired("The direction of the traffic flow is a mandatory parameter")])
+
+    #SPECIFIC PARAMETERS - Creating ACL Entry [ACL_L2]
+    source_mac          = StringField('Source MAC Address', validators=[Optional(), validate_mac_address])  
+    destination_mac     = StringField('Destination MAC Address', validators=[Optional(), validate_mac_address]) 
+
+class AddServiceForm_ACL_IPV4(FlaskForm):
+    #GENERIC SERVICE PARAMETERS (COMMON & MANDATORY)
+    service_name        = StringField('Service Name', validators=[CustomInputRequired()])
+    service_type        = SelectField('Service Type', choices=[(1, '1 (L3NM)')], validators=[CustomInputRequired()])
+    service_device_1    = SelectField('Device_1', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_device_2    = SelectField('Device_2', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_endpoint_1  = StringField('Device_1 Endpoint', validators=[CustomInputRequired()])
+    service_endpoint_2  = StringField('Device_2 Endpoint', validators=[CustomInputRequired()])
+    
+    #GENERIC SERVICE CONSTRAINT PARAMETERS (ALL OPTIONAL)
+    service_capacity    = DecimalField('Service Capacity', places=2, default=10.00, validators=[Optional(), NumberRange(min=0)])
+    service_latency     = DecimalField('Service Latency', places=2, default=15.20, validators=[Optional(), NumberRange(min=0)])
+    service_availability= DecimalField('Service Availability', places=2, validators=[Optional(), NumberRange(min=0)])
+    service_isolation   = SelectField('Service Isolation', choices=[('', 'Select (Optional)'), ('NO_ISOLATION', 'NO_ISOLATION'), ('PHYSICAL_ISOLATION', 'PHYSICAL_ISOLATION'), 
+                                                                    ('LOGICAL_ISOLATION', 'LOGICAL_ISOLATION'), ('PROCESS_ISOLATION', 'PROCESS_ISOLATION'), ('PHYSICAL_MEMORY_ISOLATION', 'PHYSICAL_MEMORY_ISOLATION'), 
+                                                                    ('PHYSICAL_NETWORK_ISOLATION', 'PHYSICAL_NETWORK_ISOLATION'), ('VIRTUAL_RESOURCE_ISOLATION', 'VIRTUAL_RESOURCE_ISOLATION'), 
+                                                                    ('NETWORK_FUNCTIONS_ISOLATION', 'NETWORK_FUNCTIONS_ISOLATION'), ('SERVICE_ISOLATION', 'SERVICE_ISOLATION')], validators=[Optional()])
+    
+    #MANDATORY_PARAMETERS
+    name                = StringField('ACL Name', validators=[CustomInputRequired("The name of the ACL is a mandatory parameter")])
+    type                = SelectField('ACL Type', choices=[('ACL_IPV4', 'ACL_IPV4')], validators=[CustomInputRequired("The type of the ACL is a mandatory parameter")])
+    sequence_id         = IntegerField('ACL Sequence ID', validators=[InputRequired(), NumberRange(min=1, message="Sequence ID must be greater than 0")])
+    forwarding_action   = SelectField('ACL Fowarding Action', choices=[(None, 'Select an action (Mandatory)'), ('ACCEPT', 'Accept'), ('DROP','Drop'),('REJECT','Reject')], validators=[InputRequired()])  
+    log_action          = SelectField('ACL Log Action', choices=[(None, 'Select a log action (Optional)'), ('LOG_SYSLOG', 'Syslog'), ('LOG_NONE','None')], validators=[Optional()]) 
+
+    #PARAMETERS FOR Associating ACL to IF 
+    interface           = StringField('Interface Name', validators=[InputRequired()])
+    subinterface        = StringField('Subinterface Index', validators=[Optional()])
+    traffic_flow        = SelectField('ACL Traffic Flow Direction', choices=[('', 'Select a direction (Mandatory)'), ('Ingress', 'Ingress'), ('Egress','Egress')], validators=[InputRequired()])
+
+    #OPTIONAL_PARAMETERS - Creating ACL Entry [ACL_IPV4]
+    source_address      = StringField('Source Address', validators=[Optional(), validate_ipv4_address])
+    destination_address = StringField('Destination Address', validators=[Optional(), validate_ipv4_address]) 
+    protocol            = IntegerField('Protocol',  validators=[Optional(),NumberRange(min=1, max=255, message="Protocol number is between 1 and 255 as defined by IANA")])
+    hop_limit           = IntegerField('Hop Limit', validators=[Optional(),NumberRange(min=1, max=255, message="The Hop limit value has to be between 0 and 255")])
+    dscp                = IntegerField('DSCP', validators=[Optional(),NumberRange(min=1, max=255, message="The DSCP value has to be between 0 and 63")])
+    source_port         = IntegerField('Source Port', validators=[Optional(),NumberRange(min=0, max=65535, message="The Port value has to be between 0 and 655535")])
+    destination_port    = IntegerField('Destination Port', validators=[Optional(),NumberRange(min=0, max=65535, message="The Port value has to be between 0 and 655535")])
+    tcp_flags           = SelectField('TCP Flags', choices=[(None, 'Select a TCP Flag (Optional)'),('TCP_SYN', 'TCP_SYN'),('TCP_ACK', 'TCP_ACK'),('TCP_RST', 'TCP_RST'),('TCP_FIN', 'TCP_FIN'),
+                                                            ('TCP_PSH', 'TCP_PSH'),('TCP_URG', 'TCP_URG') ,('TCP_ECE', 'TCP_ECE'),('TCP_CWR', 'TCP_CWR')], validators=[Optional()]) 
+
+class AddServiceForm_ACL_IPV6(FlaskForm):
+    #GENERIC SERVICE PARAMETERS (COMMON & MANDATORY)
+    service_name       = StringField('Service Name', validators=[CustomInputRequired()])
+    service_type       = SelectField('Service Type', choices=[(1, '1 (L3NM)')], validators=[CustomInputRequired()])
+    service_device_1   = SelectField('Device_1', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_device_2   = SelectField('Device_2', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_endpoint_1 = StringField('Device_1 Endpoint', validators=[CustomInputRequired()])
+    service_endpoint_2 = StringField('Device_2 Endpoint', validators=[CustomInputRequired()])
+    
+    #GENERIC SERVICE CONSTRAINT PARAMETERS (ALL OPTIONAL)
+    service_capacity    = DecimalField('Service Capacity', places=2, default=10.00, validators=[Optional(), NumberRange(min=0)])
+    service_latency     = DecimalField('Service Latency', places=2, default=15.20, validators=[Optional(), NumberRange(min=0)])
+    service_availability= DecimalField('Service Availability', places=2, validators=[Optional(), NumberRange(min=0)])
+    service_isolation   = SelectField('Service Isolation', choices=[('', 'Select (Optional)'), ('NO_ISOLATION', 'NO_ISOLATION'), ('PHYSICAL_ISOLATION', 'PHYSICAL_ISOLATION'), 
+                                                                    ('LOGICAL_ISOLATION', 'LOGICAL_ISOLATION'), ('PROCESS_ISOLATION', 'PROCESS_ISOLATION'), ('PHYSICAL_MEMORY_ISOLATION', 'PHYSICAL_MEMORY_ISOLATION'), 
+                                                                    ('PHYSICAL_NETWORK_ISOLATION', 'PHYSICAL_NETWORK_ISOLATION'), ('VIRTUAL_RESOURCE_ISOLATION', 'VIRTUAL_RESOURCE_ISOLATION'), 
+                                                                    ('NETWORK_FUNCTIONS_ISOLATION', 'NETWORK_FUNCTIONS_ISOLATION'), ('SERVICE_ISOLATION', 'SERVICE_ISOLATION')], validators=[Optional()])
+    
+    #MANDATORY_PARAMETERS
+    name                = StringField('ACL Name', validators=[InputRequired()])
+    type                = SelectField('ACL Type', choices=[('ACL_IPV6', 'ACL_IPV6')], validators=[InputRequired()])
+    sequence_id         = IntegerField('ACL Sequence ID', validators=[InputRequired(), NumberRange(min=1, message="Sequence ID must be greater than 0")])
+    forwarding_action   = SelectField('ACL Fowarding Action', choices=[(None, 'Select an action (Mandatory)'), ('ACCEPT', 'Accept'), ('DROP','Drop'),('REJECT','Reject')], validators=[InputRequired()])  
+    log_action          = SelectField('ACL Log Action', choices=[(None, 'Select a log action (Optional)'), ('LOG_SYSLOG', 'Syslog'), ('LOG_NONE','None')], validators=[Optional()]) 
+
+    #PARAMETERS FOR Associating ACL to IF 
+    interface           = StringField('Interface Name', validators=[InputRequired()])
+    subinterface        = StringField('Subinterface Index', validators=[Optional()])
+    traffic_flow        = SelectField('ACL Traffic Flow Direction', choices=[('', 'Select a direction (Mandatory)'), ('Ingress', 'Ingress'), ('Egress','Egress')], validators=[InputRequired()])
+
+    #SPECIFIC PARAMETERS - Creating ACL Entry [ACL_IPV6]
+    source_address      = StringField('Source Address', validators=[Optional(), validate_ipv6_address])
+    destination_address = StringField('Destination Address', validators=[Optional(), validate_ipv6_address])
+    protocol            = IntegerField('Protocol',  validators=[Optional(),NumberRange(min=1, max=255, message="Protocol number is between 1 and 255 as defined by IANA")])
+    hop_limit           = IntegerField('Hop Limit', validators=[Optional(),NumberRange(min=1, max=255, message="The Hop limit value has to be between 0 and 255")])
+    dscp                = IntegerField('DSCP', validators=[Optional(),NumberRange(min=1, max=255, message="The DSCP value has to be between 0 and 63")])
+
+class AddServiceForm_L2VPN(FlaskForm):
+    #GENERIC SERVICE PARAMETERS (COMMON & MANDATORY)
+    service_name       = StringField('Service Name', validators=[CustomInputRequired()])
+    service_type       = SelectField('Service Type', choices=[(2, '2 (L2NM)')], validators=[CustomInputRequired()])
+    service_device_1   = SelectField('Device_1', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_device_2   = SelectField('Device_2', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_endpoint_1 = StringField('Device_1 Endpoint', validators=[CustomInputRequired()])
+    service_endpoint_2 = StringField('Device_2 Endpoint', validators=[CustomInputRequired()])
+    
+    #GENERIC SERVICE CONSTRAINT PARAMETERS (ALL OPTIONAL)
+    service_capacity    = DecimalField('Service Capacity', places=2, default=10.00, validators=[Optional(), NumberRange(min=0)])
+    service_latency     = DecimalField('Service Latency', places=2, default=15.20, validators=[Optional(), NumberRange(min=0)])
+    service_availability= DecimalField('Service Availability', places=2, validators=[Optional(), NumberRange(min=0)])
+    service_isolation   = SelectField('Service Isolation', choices=[('', 'Select (Optional)'), ('NO_ISOLATION', 'NO_ISOLATION'), ('PHYSICAL_ISOLATION', 'PHYSICAL_ISOLATION'), 
+                                                                    ('LOGICAL_ISOLATION', 'LOGICAL_ISOLATION'), ('PROCESS_ISOLATION', 'PROCESS_ISOLATION'), ('PHYSICAL_MEMORY_ISOLATION', 'PHYSICAL_MEMORY_ISOLATION'), 
+                                                                    ('PHYSICAL_NETWORK_ISOLATION', 'PHYSICAL_NETWORK_ISOLATION'), ('VIRTUAL_RESOURCE_ISOLATION', 'VIRTUAL_RESOURCE_ISOLATION'), 
+                                                                    ('NETWORK_FUNCTIONS_ISOLATION', 'NETWORK_FUNCTIONS_ISOLATION'), ('SERVICE_ISOLATION', 'SERVICE_ISOLATION')], validators=[Optional()])
+    
+    
+    NI_name                      = StringField('NI Name', validators=[CustomInputRequired()])
+    NI_mtu                       = IntegerField('NI MTU', default=1500, validators=[CustomInputRequired(), NumberRange(min=0, message="MTU value can't be negative")])
+    NI_description               = StringField('NI Description', validators=[Optional()])
+    #Device_1 specific
+    Device_1_NI_remote_system    = StringField('Device_1 NI Remote System', validators=[CustomInputRequired(),validate_ipv4_address])
+    Device_1_NI_VC_ID            = IntegerField('Device_1 NI VC ID', validators=[CustomInputRequired(), NumberRange(min=0, message="VC can't be negative")])
+    Device_1_NI_connection_point = StringField('Device_1 NI Conection Point', validators=[CustomInputRequired()])
+    #Device_2 specific
+    Device_2_NI_remote_system    = StringField ('Device_2 NI Remote System', validators=[CustomInputRequired(),validate_ipv4_address])
+    Device_2_NI_VC_ID            = IntegerField('Device_2 NI VC ID', validators=[CustomInputRequired(), NumberRange(min=0, message="VC can't be negative")])
+    Device_2_NI_connection_point = StringField ('Device_2 NI Conection Point', validators=[CustomInputRequired()])
+     
+    #Interface parameters (DEVICE SPECIFIC)
+    Device_1_IF_index       = IntegerField('Device_1 SubIF Index', validators=[CustomInputRequired(), NumberRange(min=0, message="SubIf index can't be negative")])
+    Device_1_IF_vlan_id     = IntegerField('Device_1 VLAN ID', validators=[CustomInputRequired(), NumberRange(min=0, message="VlanID can't be negative")])
+    Device_1_IF_mtu         = IntegerField('Device_1 Interface MTU', validators=[Optional(), NumberRange(min=0, message="MTU value can't be negative")])
+    Device_1_IF_description = StringField ('Device_1 SubIF Description', validators=[Optional()])
+    
+    Device_2_IF_index       = IntegerField('Device_2 SubIF Index', validators=[CustomInputRequired(), NumberRange(min=0, message="SubIf index can't be negative")])
+    Device_2_IF_vlan_id     = IntegerField('Device_2 VLAN ID', validators=[CustomInputRequired(), NumberRange(min=0, message="VlanID can't be negative")])
+    Device_2_IF_mtu         = IntegerField('Device_2 Interface MTU', validators=[Optional(), NumberRange(min=0, message="MTU value can't be negative")])
+    Device_2_IF_description = StringField ('Device_2 SubIF Description', validators=[Optional()])
+
+class AddServiceForm_L3VPN(FlaskForm):
+    #GENERIC SERVICE PARAMETERS (COMMON & MANDATORY)
+    service_name     = StringField('Service Name', validators=[CustomInputRequired()])
+    service_type     = SelectField('Service Type', choices=[(1, '1 (L3NM)')], validators=[CustomInputRequired()])
+    service_device_1   = SelectField('Device_1', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_device_2   = SelectField('Device_2', choices=[('', 'Select a device (Mandatory)')], validators=[CustomInputRequired()])
+    service_endpoint_1 = StringField('Device_1 Endpoint', validators=[CustomInputRequired()])
+    service_endpoint_2 = StringField('Device_2 Endpoint', validators=[CustomInputRequired()])
+    
+    #GENERIC SERVICE CONSTRAINT PARAMETERS (ALL OPTIONAL)
+    service_capacity    = DecimalField('Service Capacity', places=2, default=10.00, validators=[Optional(), NumberRange(min=0)])
+    service_latency     = DecimalField('Service Latency', places=2, default=15.20, validators=[Optional(), NumberRange(min=0)])
+    service_availability= DecimalField('Service Availability', places=2, validators=[Optional(), NumberRange(min=0)])
+    service_isolation   = SelectField('Service Isolation', choices=[('', 'Select (Optional)'), ('NO_ISOLATION', 'NO_ISOLATION'), ('PHYSICAL_ISOLATION', 'PHYSICAL_ISOLATION'), 
+                                                                    ('LOGICAL_ISOLATION', 'LOGICAL_ISOLATION'), ('PROCESS_ISOLATION', 'PROCESS_ISOLATION'), ('PHYSICAL_MEMORY_ISOLATION', 'PHYSICAL_MEMORY_ISOLATION'), 
+                                                                    ('PHYSICAL_NETWORK_ISOLATION', 'PHYSICAL_NETWORK_ISOLATION'), ('VIRTUAL_RESOURCE_ISOLATION', 'VIRTUAL_RESOURCE_ISOLATION'), 
+                                                                    ('NETWORK_FUNCTIONS_ISOLATION', 'NETWORK_FUNCTIONS_ISOLATION'), ('SERVICE_ISOLATION', 'SERVICE_ISOLATION')], validators=[Optional()])
+     
+    NI_name           = StringField('Name', validators=[InputRequired()])
+    NI_route_distinguisher = StringField('Route Distinguisher', validators=[InputRequired(),validate_route_distinguisher])
+    NI_router_id      = StringField('Router ID', validators=[Optional(), validate_ipv4_address])
+    NI_description    = StringField('Description', validators=[Optional()])
+    NI_protocol       = SelectField('Protocol', choices=[('', 'Select a type (Mandatory)'),('STATIC', 'STATIC'),('DIRECTLY_CONNECTED', 'DIRECTLY_CONNECTED'),('BGP', 'BGP')], validators=[InputRequired()])  
+    NI_as             = IntegerField('AS', default=None, validators=[validate_NI_as, Optional(), validate_uint32])                      
+    NI_address_family = SelectField('Protocol Address Family', choices=[('', 'Select a type (Mandatory)'),('IPV4', 'IPV4'),('IPV6', 'IPV6')], validators=[InputRequired()])        
+    NI_default_import_policy = SelectField('Default Network Instance Import Policy', choices=[('', 'Select a policy (Mandatory)'),('ACCEPT_ROUTE', 'ACCEPT_ROUTE'),('REJECT_ROUTE', 'REJECT_ROUTE')], validators=[Optional()])                                 
+    NI_import_policy  = StringField('Name of the Network Instance Import Policy', validators=[Optional()])
+    NI_export_policy  = StringField('Name of the Network Instance Export Policy', validators=[Optional()])
+
+    ## Interface (IF) PARAMS
+    Device_1_IF_index       = IntegerField('Device_1 SubIF Index', validators=[CustomInputRequired(), NumberRange(min=0, message="SubIf index can't be negative")])
+    Device_1_IF_vlan_id     = IntegerField('Device_1 VLAN ID', validators=[CustomInputRequired(), NumberRange(min=0, message="VlanID can't be negative")])
+    Device_1_IF_mtu         = IntegerField('Device_1 Interface MTU', validators=[Optional(), NumberRange(min=0, message="MTU value can't be negative")])
+    Device_1_IF_address_ip  = StringField('Device_1 IP Address', validators=[CustomInputRequired(), validate_ipv4_address])
+    Device_1_IF_address_prefix = IntegerField('Device_1 IP Prefix length', validators=[CustomInputRequired(), validate_uint32])
+    Device_1_IF_description = StringField ('Device_1 SubIF Description', validators=[Optional()])
+    
+    Device_2_IF_index       = IntegerField('Device_2 SubIF Index', validators=[CustomInputRequired(), NumberRange(min=0, message="SubIf index can't be negative")])
+    Device_2_IF_vlan_id     = IntegerField('Device_2 VLAN ID', validators=[CustomInputRequired(), NumberRange(min=0, message="VlanID can't be negative")])
+    Device_2_IF_mtu         = IntegerField('Device_2 Interface MTU', validators=[Optional(), NumberRange(min=0, message="MTU value can't be negative")])
+    Device_2_IF_address_ip  = StringField('Device_2 IP Address', validators=[CustomInputRequired(), validate_ipv4_address])
+    Device_2_IF_address_prefix = IntegerField('Device_2 IP Prefix length', validators=[CustomInputRequired(), validate_uint32])
+    Device_2_IF_description = StringField ('Device_2 SubIF Description', validators=[Optional()])
diff --git a/src/webui/service/service/routes.py b/src/webui/service/service/routes.py
index 08312e5257d13c4b55b83733ded689c7565c4790..e0d7b4c31ad69963e0782be3d59eab9e9b74b44e 100644
--- a/src/webui/service/service/routes.py
+++ b/src/webui/service/service/routes.py
@@ -12,39 +12,50 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from contextlib import contextmanager
-import json
-import grpc
+import grpc, json, logging #, re
 from collections import defaultdict
 from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for, request
+from typing import Optional, Set
+from wtforms.validators import ValidationError
+
 from common.proto.context_pb2 import (
-    IsolationLevelEnum, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection, Empty, DeviceDriverEnum,
-    ConfigActionEnum, Device, DeviceList)
+    ContextId, IsolationLevelEnum, Service, ServiceId, ServiceTypeEnum, ServiceStatusEnum, Connection,
+    Empty, DeviceDriverEnum, ConfigActionEnum, Device, DeviceList
+)
 from common.tools.context_queries.Context import get_context
-from common.tools.context_queries.Topology import get_topology
 from common.tools.context_queries.EndPoint import get_endpoint_names
 from common.tools.context_queries.Service import get_service_by_uuid
+from common.tools.context_queries.Topology import get_topology
+from common.tools.descriptor.Loader import DescriptorLoader, compose_notifications
 from common.tools.object_factory.ConfigRule import json_config_rule_set
+from common.tools.object_factory.Constraint import (
+    json_constraint_sla_availability, json_constraint_sla_capacity, json_constraint_sla_isolation,
+    json_constraint_sla_latency
+)
 from common.tools.object_factory.Context import json_context_id
+from common.tools.object_factory.Device import json_device_id
+from common.tools.object_factory.EndPoint import json_endpoint_id
+from common.tools.object_factory.Service import json_service_l2nm_planned, json_service_l3nm_planned
 from common.tools.object_factory.Topology import json_topology_id
 from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
 from service.client.ServiceClient import ServiceClient
-from typing import Optional, Set
+from webui.service.service.forms import (
+    AddServiceForm_1, AddServiceForm_ACL_L2, AddServiceForm_ACL_IPV4, AddServiceForm_ACL_IPV6,
+    AddServiceForm_L2VPN, AddServiceForm_L3VPN
+)
 
+LOGGER = logging.getLogger(__name__)
 service = Blueprint('service', __name__, url_prefix='/service')
 
 context_client = ContextClient()
 service_client = ServiceClient()
+device_client = DeviceClient()
 
-@contextmanager
-def connected_client(c):
-    try:
-        c.connect()
-        yield c
-    finally:
-        c.close()
+ACL_TYPE = ["ACL_UNDEFINED", "ACL_IPV4","ACL_IPV6","ACL_L2","ACL_MPLS","ACL_MIXED"]
+f_action = ["UNDEFINED", "DROP","ACCEPT","REJECT"]
+l_action = ["UNDEFINED", "LOG_NONE","LOG_SYSLOG"]
 
-# Context client must be in connected state when calling this function
 def get_device_drivers_in_use(topology_uuid: str, context_uuid: str) -> Set[str]:
     active_drivers = set()
     grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False)
@@ -91,23 +102,22 @@ def home():
         'service/home.html', services=services, device_names=device_names, endpoints_data=endpoints_data,
         ste=ServiceTypeEnum, sse=ServiceStatusEnum, active_drivers=active_drivers)
 
-
 @service.route('add', methods=['GET', 'POST'])
 def add():
     flash('Add service route called', 'danger')
     raise NotImplementedError()
-    #return render_template('service/home.html')
-
 
 def get_hub_module_name(dev: Device) -> Optional[str]:
     for cr in dev.device_config.config_rules:
-        if cr.action == ConfigActionEnum.CONFIGACTION_SET and cr.custom and cr.custom.resource_key == "_connect/settings":
-            try:
-                cr_dict = json.loads(cr.custom.resource_value)
-                if "hub_module_name" in cr_dict:
-                    return cr_dict["hub_module_name"]
-            except json.JSONDecodeError:
-                pass
+        if cr.action != ConfigActionEnum.CONFIGACTION_SET: continue
+        if not cr.custom: continue
+        if cr.custom.resource_key != "_connect/settings": continue
+        try:
+            cr_dict = json.loads(cr.custom.resource_value)
+            if "hub_module_name" in cr_dict:
+                return cr_dict["hub_module_name"]
+        except json.JSONDecodeError:
+            pass
     return None
 
 @service.route('add-xr', methods=['GET', 'POST'])
@@ -125,124 +135,137 @@ def add_xr():
     if grpc_topology is None:
         flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger')
         return redirect(url_for("main.home"))
-    else:
-        topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}
-        grpc_devices= context_client.ListDevices(Empty())
-        devices = [
-            device for device in grpc_devices.devices
-            if device.device_id.device_uuid.uuid in topo_device_uuids and DeviceDriverEnum.DEVICEDRIVER_XR in device.device_drivers
-        ]
-        devices.sort(key=lambda dev: dev.name)
-
-        hub_interfaces_by_device = defaultdict(list)
-        leaf_interfaces_by_device = defaultdict(list)
-        constellation_name_to_uuid = {}
-        dev_ep_to_uuid = {}
-        ep_uuid_to_name = {}
-        for d in devices:
-            constellation_name_to_uuid[d.name] = d.device_id.device_uuid.uuid
-            hm_name = get_hub_module_name(d)
-            if hm_name is not None:
-                hm_if_prefix= hm_name + "|"
-                for ep in d.device_endpoints:
-                    dev_ep_to_uuid[(d.name, ep.name)] = ep.endpoint_id.endpoint_uuid.uuid
-                    if ep.name.startswith(hm_if_prefix):
-                        hub_interfaces_by_device[d.name].append(ep.name)
-                    else:
-                        leaf_interfaces_by_device[d.name].append(ep.name)
-                    ep_uuid_to_name[ep.endpoint_id.endpoint_uuid.uuid] = (d.name, ep.name)
-                hub_interfaces_by_device[d.name].sort()
-                leaf_interfaces_by_device[d.name].sort()
-
-        # Find out what endpoints are already used so that they can be disabled
-        # in the create screen
-        context_obj = get_context(context_client, context_uuid, rw_copy=False)
-        if context_obj is None:
-            flash('Context({:s}) not found'.format(str(context_uuid)), 'danger')
-            return redirect(request.url)
-        
-        services = context_client.ListServices(context_obj.context_id)
-        ep_used_by={}
-        for service in services.services:
-            if  service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE:
-                for ep in service.service_endpoint_ids:
-                    ep_uuid = ep.endpoint_uuid.uuid
-                    if ep_uuid in ep_uuid_to_name:
-                        dev_name, ep_name = ep_uuid_to_name[ep_uuid]
-                        ep_used_by[f"{ep_name}@{dev_name}"] = service.name
+
+    topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}
+    grpc_devices= context_client.ListDevices(Empty())
+    devices = [
+        device for device in grpc_devices.devices
+        if device.device_id.device_uuid.uuid in topo_device_uuids and DeviceDriverEnum.DEVICEDRIVER_XR in device.device_drivers
+    ]
+    devices.sort(key=lambda dev: dev.name)
+
+    hub_interfaces_by_device = defaultdict(list)
+    leaf_interfaces_by_device = defaultdict(list)
+    constellation_name_to_uuid = {}
+    dev_ep_to_uuid = {}
+    ep_uuid_to_name = {}
+    for d in devices:
+        constellation_name_to_uuid[d.name] = d.device_id.device_uuid.uuid
+        hm_name = get_hub_module_name(d)
+        if hm_name is not None:
+            hm_if_prefix= hm_name + "|"
+            for ep in d.device_endpoints:
+                dev_ep_to_uuid[(d.name, ep.name)] = ep.endpoint_id.endpoint_uuid.uuid
+                if ep.name.startswith(hm_if_prefix):
+                    hub_interfaces_by_device[d.name].append(ep.name)
+                else:
+                    leaf_interfaces_by_device[d.name].append(ep.name)
+                ep_uuid_to_name[ep.endpoint_id.endpoint_uuid.uuid] = (d.name, ep.name)
+            hub_interfaces_by_device[d.name].sort()
+            leaf_interfaces_by_device[d.name].sort()
+
+    context_obj = get_context(context_client, context_uuid, rw_copy=False)
+    if context_obj is None:
+        flash('Context({:s}) not found'.format(str(context_uuid)), 'danger')
+        return redirect(request.url)
+    
+    services = context_client.ListServices(context_obj.context_id)
+    ep_used_by={}
+    for service in services.services:
+        if  service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE:
+            for ep in service.service_endpoint_ids:
+                ep_uuid = ep.endpoint_uuid.uuid
+                if ep_uuid in ep_uuid_to_name:
+                    dev_name, ep_name = ep_uuid_to_name[ep_uuid]
+                    ep_used_by[f"{ep_name}@{dev_name}"] = service.name
 
     context_client.close()
 
     if request.method != 'POST':
-        return render_template('service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device, leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by)
-    else:
-        service_name = request.form["service_name"]
-        if service_name == "":
-            flash(f"Service name must be specified", 'danger')
-
-        constellation = request.form["constellation"]
-        constellation_uuid = constellation_name_to_uuid.get(constellation, None)
-        if constellation_uuid is None:
-            flash(f"Invalid constellation \"{constellation}\"", 'danger')
-
-        hub_if = request.form["hubif"]
-        hub_if_uuid = dev_ep_to_uuid.get((constellation, hub_if), None)
-        if hub_if_uuid is None:
-            flash(f"Invalid hub interface \"{hub_if}\"", 'danger')
-
-        leaf_if = request.form["leafif"]
-        leaf_if_uuid = dev_ep_to_uuid.get((constellation, leaf_if), None)
-        if leaf_if_uuid is None:
-            flash(f"Invalid leaf interface \"{leaf_if}\"", 'danger')
-        
-        if service_name == "" or constellation_uuid is None or hub_if_uuid is None or leaf_if_uuid is None:
+        return render_template(
+            'service/add-xr.html', devices=devices, hub_if=hub_interfaces_by_device,
+            leaf_if=leaf_interfaces_by_device, ep_used_by=ep_used_by
+        )
+
+    service_name = request.form["service_name"]
+    if service_name == "":
+        flash(f"Service name must be specified", 'danger')
+
+    constellation = request.form["constellation"]
+    constellation_uuid = constellation_name_to_uuid.get(constellation, None)
+    if constellation_uuid is None:
+        flash(f"Invalid constellation \"{constellation}\"", 'danger')
+
+    hub_if = request.form["hubif"]
+    hub_if_uuid = dev_ep_to_uuid.get((constellation, hub_if), None)
+    if hub_if_uuid is None:
+        flash(f"Invalid hub interface \"{hub_if}\"", 'danger')
+
+    leaf_if = request.form["leafif"]
+    leaf_if_uuid = dev_ep_to_uuid.get((constellation, leaf_if), None)
+    if leaf_if_uuid is None:
+        flash(f"Invalid leaf interface \"{leaf_if}\"", 'danger')
+    
+    if service_name == "" or constellation_uuid is None or hub_if_uuid is None or leaf_if_uuid is None:
+        return redirect(request.url)
+    
+    
+    json_context_uuid=json_context_id(context_uuid)
+    sr = {
+        "name": service_name,
+        "service_id": {
+                "context_id": {"context_uuid": {"uuid": context_uuid}},
+                "service_uuid": {"uuid": service_name}
+        },
+        'service_type'        : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
+        "service_endpoint_ids": [
+            {
+                'device_id': {'device_uuid': {'uuid': constellation_uuid}},
+                'endpoint_uuid': {'uuid': hub_if_uuid},
+                'topology_id': json_topology_id("admin", context_id=json_context_uuid)
+            },
+            {
+                'device_id': {'device_uuid': {'uuid': constellation_uuid}},
+                'endpoint_uuid': {'uuid': leaf_if_uuid},
+                'topology_id': json_topology_id("admin", context_id=json_context_uuid)
+            }
+        ],
+        'service_status'      : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED},
+        'service_constraints' : [],
+    }
+
+    json_tapi_settings = {
+        'capacity_value'  : 50.0,
+        'capacity_unit'   : 'GHz',
+        'layer_proto_name': 'PHOTONIC_MEDIA',
+        'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC',
+        'direction'       : 'UNIDIRECTIONAL',
+    }
+    config_rule = json_config_rule_set('/settings', json_tapi_settings)
+
+    try:
+        service_client.connect()
+
+        endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], []
+        try:
+            create_response = service_client.CreateService(Service(**sr))
+        except Exception as e:
+            flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger')
             return redirect(request.url)
         
-        
-        json_context_uuid=json_context_id(context_uuid)
-        sr = {
-            "name": service_name,
-            "service_id": {
-                 "context_id": {"context_uuid": {"uuid": context_uuid}},
-                 "service_uuid": {"uuid": service_name}
-            },
-            'service_type'        : ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE,
-            "service_endpoint_ids": [
-                {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': hub_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)},
-                {'device_id': {'device_uuid': {'uuid': constellation_uuid}}, 'endpoint_uuid': {'uuid': leaf_if_uuid}, 'topology_id': json_topology_id("admin", context_id=json_context_uuid)}
-            ],
-            'service_status'      : {'service_status': ServiceStatusEnum.SERVICESTATUS_PLANNED},
-            'service_constraints' : [],
-        }
+        sr['service_endpoint_ids'] = endpoints
+        sr['service_config'] = {'config_rules': [config_rule]}
 
-        json_tapi_settings = {
-            'capacity_value'  : 50.0,
-            'capacity_unit'   : 'GHz',
-            'layer_proto_name': 'PHOTONIC_MEDIA',
-            'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC',
-            'direction'       : 'UNIDIRECTIONAL',
-        }
-        config_rule = json_config_rule_set('/settings', json_tapi_settings)
-
-        with connected_client(service_client) as sc:
-            endpoints, sr['service_endpoint_ids'] = sr['service_endpoint_ids'], []
-            try:
-                create_response = sc.CreateService(Service(**sr))
-            except Exception as e:
-                flash(f'Failure to update service name {service_name} with endpoints and configuration, exception {str(e)}', 'danger')
-                return redirect(request.url)
-            
-            sr['service_endpoint_ids'] = endpoints
-            sr['service_config'] = {'config_rules': [config_rule]}
-
-            try:
-                update_response = sc.UpdateService(Service(**sr))
-                flash(f'Created service {update_response.service_uuid.uuid}', 'success')
-            except Exception as e: 
-                flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger')
-                return redirect(request.url)
+        try:
+            update_response = service_client.UpdateService(Service(**sr))
+            flash(f'Created service {update_response.service_uuid.uuid}', 'success')
+        except Exception as e: 
+            flash(f'Failure to update service {create_response.service_uuid.uuid} with endpoints and configuration, exception {str(e)}', 'danger')
+            return redirect(request.url)
 
-            return redirect(url_for('service.home'))
+        return redirect(url_for('service.home'))
+    finally:
+        service_client.close()
 
 @service.get('<path:service_uuid>/detail')
 def detail(service_uuid: str):
@@ -253,7 +276,6 @@ def detail(service_uuid: str):
 
     try:
         context_client.connect()
-
         endpoint_ids = list()
         service_obj = get_service_by_uuid(context_client, service_uuid, rw_copy=False)
         if service_obj is None:
@@ -271,16 +293,16 @@ def detail(service_uuid: str):
             device_names, endpoints_data = dict(), dict()
 
         context_client.close()
-
         return render_template(
             'service/detail.html', service=service_obj, connections=connections, device_names=device_names,
-            endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum, ile=IsolationLevelEnum)
+            endpoints_data=endpoints_data, ste=ServiceTypeEnum, sse=ServiceStatusEnum, ile=IsolationLevelEnum,
+            type=ACL_TYPE, f_action=f_action, l_action=l_action
+        )
     except Exception as e:
         flash('The system encountered an error and cannot show the details of this service.', 'warning')
         current_app.logger.exception(e)
         return redirect(url_for('service.home'))
 
-
 @service.get('<path:service_uuid>/delete')
 def delete(service_uuid: str):
     if 'context_uuid' not in session or 'topology_uuid' not in session:
@@ -301,3 +323,351 @@ def delete(service_uuid: str):
         flash('Problem deleting service "{:s}": {:s}'.format(service_uuid, str(e.details())), 'danger')
         current_app.logger.exception(e)
     return redirect(url_for('service.home'))
+
+@service.route('add/configure', methods=['GET', 'POST'])
+def add_configure():
+    form_1 = AddServiceForm_1()
+    if form_1.validate_on_submit():
+        service_type = str(form_1.service_type.data)
+        if service_type in {'ACL_L2', 'ACL_IPV4', 'ACL_IPV6', 'L2VPN', 'L3VPN'}:
+            return redirect(url_for('service.add_configure_{:s}'.format(service_type)))
+    return render_template('service/add.html', form_1=form_1, submit_text='Continue to configuraton')
+
+@service.route('add/configure/ACL_L2', methods=['GET', 'POST'])
+def add_configure_ACL_L2():
+    form_acl = AddServiceForm_ACL_L2()
+    service_obj = Service()   
+
+    context_uuid, topology_uuid = get_context_and_topology_uuids()
+    if context_uuid and topology_uuid:
+        context_client.connect()
+        grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False)
+        if grpc_topology:
+            topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}          
+            context_obj = get_context(context_client, context_uuid, rw_copy=False)
+            if context_obj is None:
+                flash('Context({:s}) not found'.format(str(context_uuid)), 'danger')
+                return redirect(request.url)
+            services = context_client.ListServices(context_obj.context_id)
+            devices = []
+            for service in services.services:
+                devices_services = []
+                if  service.service_type == ServiceTypeEnum.SERVICETYPE_L2NM:
+                    LOGGER.warning('L2NM service')  
+                    for ep in service.service_endpoint_ids:
+                        device_uuid = ep.device_id.device_uuid.uuid
+                        devices_services.append(device_uuid, service.service_name)
+                        LOGGER.warning('device_uuid')  
+                        LOGGER.warning(device_uuid)  
+                    
+                    grpc_devices = context_client.ListDevices(Empty())                                          
+                    for device in grpc_devices.devices:
+                        if device.device_id.device_uuid.uuid in devices_services:
+                            devices.append(device)
+           
+            choices = get_device_choices(devices)
+            add_device_choices_to_form(choices, form_acl.service_device_1)
+            add_device_choices_to_form(choices, form_acl.service_device_2)
+        else:
+            flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger')
+    else:
+        flash('Missing context or topology UUID', 'danger')
+    if form_acl.validate_on_submit():    
+        flash(f'New configuration was created', 'success')
+        return redirect(url_for('service.home'))
+    
+    return render_template('service/configure_ACL_L2.html', form_acl=form_acl, submit_text='Add New Service')
+
+@service.route('add/configure/ACL_IPV4', methods=['GET', 'POST'])
+def add_configure_ACL_IPV4():
+    form_acl = AddServiceForm_ACL_IPV4()
+    if form_acl.validate_on_submit():
+        flash(f'New configuration was created', 'success')
+        return redirect(url_for('service.home'))
+    print(form_acl.errors)
+    return render_template('service/configure_ACL_IPV4.html', form_acl=form_acl, submit_text='Add New Service')
+
+@service.route('add/configure/ACL_IPV6', methods=['GET', 'POST'])
+def add_configure_ACL_IPV6():
+    form_acl = AddServiceForm_ACL_IPV6()
+    if form_acl.validate_on_submit():
+        flash(f'New configuration was created', 'success')
+        return redirect(url_for('service.home'))
+    print(form_acl.errors)
+    return render_template('service/configure_ACL_IPV6.html', form_acl=form_acl, submit_text='Add New Service')
+ 
+@service.route('add/configure/L2VPN', methods=['GET', 'POST'])
+def add_configure_L2VPN():
+    form_l2vpn = AddServiceForm_L2VPN()
+    service_obj = Service()
+
+    context_uuid, topology_uuid = get_context_and_topology_uuids()
+    if context_uuid and topology_uuid:
+        context_client.connect()
+        grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False)
+        if grpc_topology:
+            topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}          
+            devices = get_filtered_devices(context_client, topo_device_uuids)
+            choices = get_device_choices(devices)
+            add_device_choices_to_form(choices, form_l2vpn.service_device_1)
+            add_device_choices_to_form(choices, form_l2vpn.service_device_2)
+        else:
+            flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger')
+    else:
+        flash('Missing context or topology UUID', 'danger')
+
+    if form_l2vpn.validate_on_submit():
+        try:
+            [selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2] = validate_selected_devices_and_endpoints(form_l2vpn, devices)
+        except Exception as e:
+            flash('{:s}'.format(str(e.args[0])), 'danger')
+            current_app.logger.exception(e)
+            return render_template('service/configure_L2VPN.html', form_l2vpn=form_l2vpn, submit_text='Add New Service')
+
+        [vendor_1, vendor_2] = get_device_vendor(form_l2vpn, devices)
+        try:
+            validate_params_vendor(form_l2vpn, vendor_1, 1)
+            validate_params_vendor(form_l2vpn, vendor_2, 2)
+        except Exception as e:       
+            flash('{:s}'.format(str(e.args[0])), 'danger')
+            current_app.logger.exception(e)
+            return render_template('service/configure_L2VPN.html', form_l2vpn=form_l2vpn, submit_text='Add New Service')
+
+        service_uuid, service_type, endpoint_ids = set_service_parameters(service_obj, form_l2vpn, selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2)
+        constraints = add_constraints(form_l2vpn)
+        params_device_1_with_data = get_device_params(form_l2vpn, 1, service_type)
+        params_device_2_with_data = get_device_params(form_l2vpn, 2, service_type)
+        print(params_device_1_with_data)
+        print(params_device_2_with_data)
+        params_settings = {}
+        config_rules = [
+            json_config_rule_set(
+                    '/settings', params_settings
+                ),
+            json_config_rule_set(
+                '/device[{:s}]/endpoint[{:s}]/settings'.format(str(selected_device_1.name), str(selected_endpoint_1)), params_device_1_with_data
+            ),
+            json_config_rule_set(
+                '/device[{:s}]/endpoint[{:s}]/settings'.format(str(selected_device_2.name), str(selected_endpoint_2)), params_device_2_with_data
+            )
+        ]
+        service_client.connect()
+        context_client.connect()
+        device_client.connect()
+        descriptor_json = json_service_l2nm_planned(service_uuid = service_uuid, endpoint_ids = endpoint_ids, constraints = constraints, config_rules = config_rules, context_uuid= context_uuid)
+        descriptor_json = {"services": [descriptor_json]}
+        try:
+            process_descriptors(descriptor_json)
+            flash('Service "{:s}" added successfully!'.format(service_obj.service_id.service_uuid.uuid), 'success')
+            return redirect(url_for('service.home', service_uuid=service_obj.service_id.service_uuid.uuid))
+        except Exception as e:
+            flash('Problem adding service: {:s}'.format((str(e.args[0]))), 'danger')
+            current_app.logger.exception(e)
+        finally:
+            context_client.close()                                                                                      
+            device_client.close()
+            service_client.close()
+    return render_template('service/configure_L2VPN.html', form_l2vpn=form_l2vpn, submit_text='Add New Service')
+
+@service.route('add/configure/L3VPN', methods=['GET', 'POST'])
+def add_configure_L3VPN():
+    form_l3vpn = AddServiceForm_L3VPN()
+    service_obj = Service()
+
+    context_uuid, topology_uuid = get_context_and_topology_uuids()
+    if context_uuid and topology_uuid:
+        context_client.connect()
+        grpc_topology = get_topology(context_client, topology_uuid, context_uuid=context_uuid, rw_copy=False)
+        if grpc_topology:
+            topo_device_uuids = {device_id.device_uuid.uuid for device_id in grpc_topology.device_ids}          
+            devices = get_filtered_devices(context_client, topo_device_uuids)
+            choices = get_device_choices(devices)
+            add_device_choices_to_form(choices, form_l3vpn.service_device_1)
+            add_device_choices_to_form(choices, form_l3vpn.service_device_2)
+        else:
+            flash('Context({:s})/Topology({:s}) not found'.format(str(context_uuid), str(topology_uuid)), 'danger')
+    else:
+        flash('Missing context or topology UUID', 'danger')
+
+    if form_l3vpn.validate_on_submit():
+        try:
+            [selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2] = validate_selected_devices_and_endpoints(form_l3vpn, devices)
+        except Exception as e:
+            flash('{:s}'.format(str(e.args[0])), 'danger')
+            current_app.logger.exception(e)
+            return render_template('service/configure_L3VPN.html', form_l3vpn=form_l3vpn, submit_text='Add New Service')
+        
+        service_uuid, service_type, endpoint_ids = set_service_parameters(service_obj, form_l3vpn, selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2)
+        constraints = add_constraints(form_l3vpn)
+        params_device_1_with_data = get_device_params(form_l3vpn, 1, service_type)
+        params_device_2_with_data = get_device_params(form_l3vpn, 2, service_type)
+        params_settings = {}
+        config_rules = [
+            json_config_rule_set(
+                    '/settings', params_settings
+                ),
+            json_config_rule_set(
+                '/device[{:s}]/endpoint[{:s}]/settings'.format(str(selected_device_1.name), str(selected_endpoint_1)), params_device_1_with_data
+            ),
+            json_config_rule_set(
+                '/device[{:s}]/endpoint[{:s}]/settings'.format(str(selected_device_2.name), str(selected_endpoint_2)), params_device_2_with_data
+            )
+        ]
+        service_client.connect()
+        context_client.connect()
+        device_client.connect()
+        descriptor_json = json_service_l3nm_planned(service_uuid = service_uuid, endpoint_ids = endpoint_ids, constraints = constraints, config_rules = config_rules, context_uuid= context_uuid)
+        descriptor_json = {"services": [descriptor_json]}
+        try:
+            process_descriptors(descriptor_json)
+            flash('Service "{:s}" added successfully!'.format(service_obj.service_id.service_uuid.uuid), 'success')
+            return redirect(url_for('service.home', service_uuid=service_obj.service_id.service_uuid.uuid))
+        except Exception as e:
+            flash('Problem adding service: {:s}'.format((str(e.args[0]))), 'danger')
+            current_app.logger.exception(e)
+        finally:
+            context_client.close()                                                                                        
+            device_client.close()
+            service_client.close()
+    return render_template('service/configure_L3VPN.html', form_l3vpn=form_l3vpn, submit_text='Add New Service')
+
+
+DESCRIPTOR_LOADER_NUM_WORKERS = 10
+
+def process_descriptors(descriptors):
+    descriptor_loader = DescriptorLoader(descriptors, num_workers=DESCRIPTOR_LOADER_NUM_WORKERS)
+    results = descriptor_loader.process()
+    for message,level in compose_notifications(results):
+        if level == 'error':                                                                                
+            LOGGER.warning('ERROR message={:s}'.format(str(message)))
+        flash(message, level)
+
+
+def get_context_and_topology_uuids():
+    context_uuid = session.get('context_uuid')
+    topology_uuid = session.get('topology_uuid')
+    return context_uuid, topology_uuid
+
+def get_filtered_devices(context_client, topo_device_uuids):
+    grpc_devices = context_client.ListDevices(Empty())                                          
+    return [device for device in grpc_devices.devices if device.device_id.device_uuid.uuid in topo_device_uuids]
+
+def get_device_choices(devices):
+    return [(i, str(device.name)) for i, device in enumerate(devices)]
+
+def add_device_choices_to_form(choices, form):
+    form.choices += choices
+
+def validate_selected_devices_and_endpoints(form, devices):
+    selected_device_1 = devices[int(form.service_device_1.data)]
+    selected_device_2 = devices[int(form.service_device_2.data)]
+    if selected_device_1 == selected_device_2:
+        raise ValidationError('The devices must be different!. Please select two valid and different devices')
+    elif form.service_endpoint_1.data not in [endpoint.name for endpoint in selected_device_1.device_endpoints]:
+        raise ValidationError('The selected endpoint: ' + form.service_endpoint_1.data + ' is not a valid endpoint for: '+ selected_device_1.name + '. Please select an endpoint that is available for this device')
+    elif form.service_endpoint_2.data not in [endpoint.name for endpoint in selected_device_2.device_endpoints]:
+        raise ValidationError('The selected endpoint: ' + form.service_endpoint_2.data + ' is not a valid endpoint for: '+ selected_device_2.name + '. Please select an endpoint that is available for this device')
+    else:
+        selected_endpoint_1 = form.service_endpoint_1.data
+        selected_endpoint_2 = form.service_endpoint_2.data
+    return selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2
+
+def get_device_vendor(form, devices):
+    selected_device_1 = devices[int(form.service_device_1.data)]
+    selected_device_2 = devices[int(form.service_device_2.data)]
+    
+    vendor_value_1 = None
+    vendor_value_2 = None
+
+    for config_rule in selected_device_1.device_config.config_rules:
+        if "vendor" in config_rule.custom.resource_value:
+            vendor_config_rule_1 = config_rule.custom.resource_value
+            config_rule_dict_1 = json.loads(vendor_config_rule_1)
+            if "vendor" in config_rule_dict_1:
+                vendor_value_1 = config_rule_dict_1["vendor"]
+            break
+
+    for config_rule in selected_device_2.device_config.config_rules:
+        if "vendor" in config_rule.custom.resource_value:
+            vendor_config_rule_2 = config_rule.custom.resource_value
+            config_rule_dict_2 = json.loads(vendor_config_rule_2)
+            if "vendor" in config_rule_dict_2:
+                vendor_value_2 = config_rule_dict_2["vendor"]
+            break
+
+    return vendor_value_1, vendor_value_2
+
+def validate_params_vendor(form, vendor, device_num):
+    if vendor != "ADVA": return
+
+    if form.NI_name.data != f"ELAN-AC:{getattr(form, f'Device_{device_num}_IF_vlan_id').data}":
+        raise ValidationError('For an ADVA device, the name of the Network Instance should have this name: "ELAN-AC:vlanID"')
+
+    elif getattr(form, f'Device_{device_num}_NI_VC_ID').data != getattr(form, f'Device_{device_num}_IF_vlan_id').data:
+        raise ValidationError('For an ADVA device, the value of the VlanID and the value of the VC_ID must be the same')
+
+def set_service_parameters(service_obj, form, selected_device_1, selected_device_2, selected_endpoint_1, selected_endpoint_2):
+    service_obj.service_id.service_uuid.uuid = str(form.service_name.data)
+    service_uuid = service_obj.service_id.service_uuid.uuid
+    service_obj.service_type = int(form.service_type.data)
+    service_type = service_obj.service_type
+
+    endpoint_ids = [
+        json_endpoint_id(json_device_id(selected_device_1.name), str(selected_endpoint_1)),
+        json_endpoint_id(json_device_id(selected_device_2.name), str(selected_endpoint_2))
+    ]
+    return service_uuid, service_type, endpoint_ids
+
+def add_constraints(form):
+    constraints = []
+    if form.service_capacity.data:
+        constraints.append(json_constraint_sla_capacity(float(form.service_capacity.data)))
+    if form.service_latency.data:
+        constraints.append(json_constraint_sla_latency(float(form.service_latency.data)))
+    if form.service_availability.data:
+        constraints.append(json_constraint_sla_availability(1, True, float(form.service_availability.data)))
+    if form.service_isolation.data is not None and form.service_isolation.data != '':
+        constraints.append(json_constraint_sla_isolation([getattr(IsolationLevelEnum, str(form.service_isolation.data))]))
+
+    return constraints
+
+def get_device_params(form, device_num, form_type):
+    if form_type == 2:
+        device_params = {
+            'ni_name': str(getattr(form, 'NI_name').data),
+            'sub_interface_index': str(getattr(form, f'Device_{device_num}_IF_index').data),
+            'vlan_id': str(getattr(form, f'Device_{device_num}_IF_vlan_id').data),
+            'remote_router': str(getattr(form, f'Device_{device_num}_NI_remote_system').data),
+            'vc_id': str(getattr(form, f'Device_{device_num}_NI_VC_ID').data),
+            'conn_point': str(getattr(form, f'Device_{device_num}_NI_connection_point').data),
+            'mtu': str(getattr(form, f'Device_{device_num}_IF_mtu').data),
+            'ni_description': str(getattr(form, 'NI_description').data),
+            'subif_description': str(getattr(form, f'Device_{device_num}_IF_description').data),
+        }
+    elif form_type == 1:
+        if device_num == 1:
+            policy_az_field = 'NI_import_policy'
+            policy_za_field = 'NI_export_policy'
+        elif device_num == 2:
+            policy_az_field = 'NI_export_policy'
+            policy_za_field = 'NI_import_policy'
+        device_params = {
+            'ni_name': str(getattr(form, 'NI_name').data),
+            'bgp_as':str(getattr(form, 'NI_as').data),
+            'route_distinguisher': str(getattr(form, 'NI_route_distinguisher').data),
+            'sub_interface_index': str(getattr(form, f'Device_{device_num}_IF_index').data),
+            'router_id': str(getattr(form, 'NI_router_id').data),
+            'vlan_id': str(getattr(form, f'Device_{device_num}_IF_vlan_id').data),
+            'address_ip': str(getattr(form, f'Device_{device_num}_IF_address_ip').data),
+            'address_prefix': str(getattr(form, f'Device_{device_num}_IF_address_prefix').data),
+            'policy_AZ': str(getattr(form, policy_az_field).data),
+            'policy_ZA': str(getattr(form, policy_za_field).data),
+            'mtu': str(getattr(form, f'Device_{device_num}_IF_mtu').data),
+            'ni_description': str(getattr(form, 'NI_description').data),
+            'subif_description': str(getattr(form, f'Device_{device_num}_IF_description').data),
+        }
+    else:
+        raise ValueError(f'Unsupported form type: {form_type}')
+
+    params_with_data = {k: v for k, v in device_params.items() if v is not None and str(v) != 'None' and v != ''}
+    return params_with_data
diff --git a/src/webui/service/templates/service/add.html b/src/webui/service/templates/service/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..2b03ebcbf05a759606861a675b1a9e76e12df47b
--- /dev/null
+++ b/src/webui/service/templates/service/add.html
@@ -0,0 +1,53 @@
+<!--
+ Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Add New Service</h1>
+<form method="POST" action="{{ url_for('service.add_configure') }}">
+    <fieldset>
+        
+        <div class="row mb-3">
+            {{ form_1.hidden_tag() }}
+        </div> 
+        <div class="row mb-3">
+            {{ form_1.service_type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_1.service_type.errors %}
+                {{ form_1.service_type(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_1.service_type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_1.service_type(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <button type="submit" class="btn btn-primary">
+            <i class="bi bi-plus-circle-fill"></i>
+            {{ submit_text }}
+        </button>
+        <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Cancel
+        </button>
+    </div>
+    </fieldset>
+</form>
+{% endblock %}
+
diff --git a/src/webui/service/templates/service/configure_ACL_IPV4.html b/src/webui/service/templates/service/configure_ACL_IPV4.html
new file mode 100644
index 0000000000000000000000000000000000000000..43262ebee8798c1fa7bb658acd68d5a5a4386293
--- /dev/null
+++ b/src/webui/service/templates/service/configure_ACL_IPV4.html
@@ -0,0 +1,433 @@
+<!--
+ Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Add New Service [ACL-IPV4]</h1>
+<form method="POST" action="{{ url_for('service.add_configure_ACL_IPV4') }}">
+    <fieldset>
+        <div class="row mb-3">
+            {{ form_acl.hidden_tag() }}
+        </div> 
+        <h3>Generic Service Parameters</h3>
+        {% if form_acl.acl_params is not none %}
+        <div class="row mb-3">
+            {{ form_acl.service_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_name.errors %}
+                {{ form_acl.service_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_type.errors %}
+                {{ form_acl.service_type(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_type(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_device_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_device_1.errors %}
+                {{ form_acl.service_device_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_device_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_device_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_acl.service_device_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_device_2.errors %}
+                {{ form_acl.service_device_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_device_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_device_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_endpoint_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_endpoint_1.errors %}
+                {{ form_acl.service_endpoint_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_endpoint_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_endpoint_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_acl.service_endpoint_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_endpoint_2.errors %}
+                {{ form_acl.service_endpoint_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_endpoint_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_endpoint_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Generic Service Constraints</h3>
+        <div class="row mb-3">
+            {{ form_acl.service_capacity.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_capacity.errors %}
+                {{ form_acl.service_capacity(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_capacity.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_capacity(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_latency.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_latency.errors %}
+                {{ form_acl.service_latency(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_latency.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_latency(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_availability.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_availability.errors %}
+                {{ form_acl.service_availability(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_availability.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_availability(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_isolation.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_isolation.errors %}
+                {{ form_acl.service_isolation(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_isolation.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_isolation(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>       
+        <h3>Specific Service Parameters</h3>
+        </br>
+        <h4>Generic ACL Parameters</h4>
+        <div class="row mb-3">
+            {{ form_acl.name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.name.errors %}
+                {{ form_acl.name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.type.errors %}
+                {{ form_acl.type(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.type(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.sequence_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.sequence_id.errors %}
+                {{ form_acl.sequence_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.sequence_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.sequence_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.forwarding_action.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.forwarding_action.errors %}
+                {{ form_acl.forwarding_action(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.forwarding_action.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.forwarding_action(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.log_action.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.log_action.errors %}
+                {{ form_acl.log_action(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.log_action.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.log_action(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.traffic_flow.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.traffic_flow.errors %}
+                {{ form_acl.traffic_flow(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.traffic_flow.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.traffic_flow(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.interface.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.interface.errors %}
+                {{ form_acl.interface(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.interface.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.interface(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.subinterface.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.subinterface.errors %}
+                {{ form_acl.subinterface(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.subinterface.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.subinterface(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h4>Specific ACL_IPV4 Parameters</h4>
+        <div class="row mb-3">
+            {{ form_acl.source_address.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.source_address.errors %}
+                {{ form_acl.source_address(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.source_address.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.source_address(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.destination_address.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.destination_address.errors %}
+                {{ form_acl.destination_address(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.destination_address.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.destination_address(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.protocol.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.protocol.errors %}
+                {{ form_acl.protocol(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.protocol.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.protocol(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.hop_limit.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.hop_limit.errors %}
+                {{ form_acl.hop_limit(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.hop_limit.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.hop_limit(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.dscp.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.dscp.errors %}
+                {{ form_acl.dscp(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.dscp.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.dscp(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.source_port.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.source_port.errors %}
+                {{ form_acl.source_port(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.source_port.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.source_port(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.destination_port.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.destination_port.errors %}
+                {{ form_acl.destination_port(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.destination_port.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.destination_port(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.tcp_flags.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.tcp_flags.errors %}
+                {{ form_acl.tcp_flags(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.tcp_flags.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.tcp_flags(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        {% endif %}
+        <button type="submit" class="btn btn-primary">
+            <i class="bi bi-plus-circle-fill"></i>
+            {{ submit_text }}
+        </button>
+        <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Cancel
+        </button>
+    </fieldset>
+    </form>
+    {% endblock %}
diff --git a/src/webui/service/templates/service/configure_ACL_IPV6.html b/src/webui/service/templates/service/configure_ACL_IPV6.html
new file mode 100644
index 0000000000000000000000000000000000000000..2fb2efbc6b4e6e57cde27315e779e2321a510eac
--- /dev/null
+++ b/src/webui/service/templates/service/configure_ACL_IPV6.html
@@ -0,0 +1,388 @@
+<!--
+ Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Add New Service [ACL-IPV6]</h1>
+<form method="POST" action="{{ url_for('service.add_configure_ACL_IPV6') }}">
+    <fieldset>
+        <div class="row mb-3">
+            {{ form_acl.hidden_tag() }}
+        </div> 
+        <h3>Generic Service Parameters</h3>
+        {% if form_acl.acl_params is not none %}
+        <div class="row mb-3">
+            {{ form_acl.service_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_name.errors %}
+                {{ form_acl.service_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_type.errors %}
+                {{ form_acl.service_type(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_type(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_device_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_device_1.errors %}
+                {{ form_acl.service_device_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_device_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_device_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_acl.service_device_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_device_2.errors %}
+                {{ form_acl.service_device_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_device_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_device_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_endpoint_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_endpoint_1.errors %}
+                {{ form_acl.service_endpoint_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_endpoint_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_endpoint_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_acl.service_endpoint_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_endpoint_2.errors %}
+                {{ form_acl.service_endpoint_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_endpoint_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_endpoint_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Generic Service Constraints</h3>
+        <div class="row mb-3">
+            {{ form_acl.service_capacity.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_capacity.errors %}
+                {{ form_acl.service_capacity(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_capacity.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_capacity(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_latency.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_latency.errors %}
+                {{ form_acl.service_latency(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_latency.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_latency(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_availability.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_availability.errors %}
+                {{ form_acl.service_availability(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_availability.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_availability(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_isolation.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_isolation.errors %}
+                {{ form_acl.service_isolation(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_isolation.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_isolation(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Specific Service Parameters</h3>
+        </br>
+        <h4>Generic ACL Parameters</h4>
+        <div class="row mb-3">
+            {{ form_acl.name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.name.errors %}
+                {{ form_acl.name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.type.errors %}
+                {{ form_acl.type(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.type(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.sequence_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.sequence_id.errors %}
+                {{ form_acl.sequence_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.sequence_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.sequence_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.forwarding_action.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.forwarding_action.errors %}
+                {{ form_acl.forwarding_action(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.forwarding_action.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.forwarding_action(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.log_action.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.log_action.errors %}
+                {{ form_acl.log_action(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.log_action.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.log_action(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.traffic_flow.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.traffic_flow.errors %}
+                {{ form_acl.traffic_flow(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.traffic_flow.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.traffic_flow(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.interface.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.interface.errors %}
+                {{ form_acl.interface(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.interface.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.interface(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.subinterface.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.subinterface.errors %}
+                {{ form_acl.subinterface(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.subinterface.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.subinterface(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h4>Specific ACL_IPV6 Parameters</h4>
+        <div class="row mb-3">
+            {{ form_acl.source_address.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.source_address.errors %}
+                {{ form_acl.source_address(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.source_address.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.source_address(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.destination_address.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.destination_address.errors %}
+                {{ form_acl.destination_address(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.destination_address.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.destination_address(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.protocol.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.protocol.errors %}
+                {{ form_acl.protocol(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.protocol.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.protocol(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.hop_limit.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.hop_limit.errors %}
+                {{ form_acl.hop_limit(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.hop_limit.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.hop_limit(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.dscp.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.dscp.errors %}
+                {{ form_acl.dscp(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.dscp.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.dscp(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        {% endif %}
+        <button type="submit" class="btn btn-primary">
+            <i class="bi bi-plus-circle-fill"></i>
+            {{ submit_text }}
+        </button>
+        <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Cancel
+        </button>
+    </fieldset>
+    </form>
+    {% endblock %}
diff --git a/src/webui/service/templates/service/configure_ACL_L2.html b/src/webui/service/templates/service/configure_ACL_L2.html
new file mode 100644
index 0000000000000000000000000000000000000000..41cd705478c9fba0c8b1445f2c8b1ce97696876c
--- /dev/null
+++ b/src/webui/service/templates/service/configure_ACL_L2.html
@@ -0,0 +1,343 @@
+<!--
+ Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Add New Service [ACL-L2]</h1>
+<form method="POST" action="{{ url_for('service.add_configure_ACL_L2') }}">
+    <fieldset>
+        <div class="row mb-3">
+            {{ form_acl.hidden_tag() }}
+        </div> 
+        <h3>Generic Service Parameters</h3>
+        {% if form_acl.acl_params is not none %}
+        <div class="row mb-3">
+            {{ form_acl.service_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_name.errors %}
+                {{ form_acl.service_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_type.errors %}
+                {{ form_acl.service_type(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_type(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_device_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_device_1.errors %}
+                {{ form_acl.service_device_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_device_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_device_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_acl.service_device_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_device_2.errors %}
+                {{ form_acl.service_device_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_device_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_device_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_endpoint_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_endpoint_1.errors %}
+                {{ form_acl.service_endpoint_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_endpoint_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_endpoint_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_acl.service_endpoint_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_acl.service_endpoint_2.errors %}
+                {{ form_acl.service_endpoint_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_endpoint_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_endpoint_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Generic Service Constraints</h3>
+        <div class="row mb-3">
+            {{ form_acl.service_capacity.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_capacity.errors %}
+                {{ form_acl.service_capacity(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_capacity.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_capacity(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_latency.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_latency.errors %}
+                {{ form_acl.service_latency(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_latency.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_latency(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_availability.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_availability.errors %}
+                {{ form_acl.service_availability(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_availability.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_availability(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.service_isolation.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.service_isolation.errors %}
+                {{ form_acl.service_isolation(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.service_isolation.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.service_isolation(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Specific Service Parameters</h3>
+        </br>
+        <h4>Generic ACL Parameters</h4>
+        <div class="row mb-3">
+            {{ form_acl.name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.name.errors %}
+                {{ form_acl.name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.type.errors %}
+                {{ form_acl.type(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.type(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.sequence_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.sequence_id.errors %}
+                {{ form_acl.sequence_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.sequence_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.sequence_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.forwarding_action.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.forwarding_action.errors %}
+                {{ form_acl.forwarding_action(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.forwarding_action.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.forwarding_action(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.log_action.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.log_action.errors %}
+                {{ form_acl.log_action(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.log_action.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.log_action(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.traffic_flow.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.traffic_flow.errors %}
+                {{ form_acl.traffic_flow(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.traffic_flow.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.traffic_flow(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.interface.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.interface.errors %}
+                {{ form_acl.interface(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.interface.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.interface(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.subinterface.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.subinterface.errors %}
+                {{ form_acl.subinterface(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.subinterface.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.subinterface(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h4>Specific ACL_L2 Parameters</h4>
+        <div class="row mb-3">
+            {{ form_acl.source_mac.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.source_mac.errors %}
+                {{ form_acl.source_mac(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.source_mac.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.source_mac(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_acl.destination_mac.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_acl.destination_mac.errors %}
+                {{ form_acl.destination_mac(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_acl.destination_mac.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_acl.destination_mac(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>   
+        {% endif %}
+        <button type="submit" class="btn btn-primary">
+            <i class="bi bi-plus-circle-fill"></i>
+            {{ submit_text }}
+        </button>
+        <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Cancel
+        </button>
+    </fieldset>
+    </form>
+    {% endblock %}
diff --git a/src/webui/service/templates/service/configure_L2VPN.html b/src/webui/service/templates/service/configure_L2VPN.html
new file mode 100644
index 0000000000000000000000000000000000000000..c443a024d3f00d70c29b70e394a67c595b27cc69
--- /dev/null
+++ b/src/webui/service/templates/service/configure_L2VPN.html
@@ -0,0 +1,434 @@
+<!--
+ Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Add New Service [L2VPN]</h1>
+<form method="POST" action="{{ url_for('service.add_configure_L2VPN') }}">
+    <fieldset>
+        <div class="row mb-3">
+            {{ form_l2vpn.hidden_tag() }}
+        </div> 
+        {% if form_l2vpn.l2vpn_params is not none %}
+        <h3>Generic Service Parameters</h3>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.service_name.errors %}
+                {{ form_l2vpn.service_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.service_type.errors %}
+                {{ form_l2vpn.service_type(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_type(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_device_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.service_device_1.errors %}
+                {{ form_l2vpn.service_device_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_device_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_device_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.service_device_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.service_device_2.errors %}
+                {{ form_l2vpn.service_device_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_device_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_device_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_endpoint_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.service_endpoint_1.errors %}
+                {{ form_l2vpn.service_endpoint_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_endpoint_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_endpoint_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.service_endpoint_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.service_endpoint_2.errors %}
+                {{ form_l2vpn.service_endpoint_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_endpoint_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_endpoint_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <h3>Generic Service Constraints</h3>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_capacity.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.service_capacity.errors %}
+                {{ form_l2vpn.service_capacity(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_capacity.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_capacity(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_latency.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.service_latency.errors %}
+                {{ form_l2vpn.service_latency(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_latency.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_latency(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_availability.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.service_availability.errors %}
+                {{ form_l2vpn.service_availability(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_availability.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_availability(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.service_isolation.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.service_isolation.errors %}
+                {{ form_l2vpn.service_isolation(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.service_isolation.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.service_isolation(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Specific Service Parameters</h3>
+        </br>
+        <h4>Network Instance (NI) Parameters</h4>
+        <div class="row mb-3">
+            {{ form_l2vpn.NI_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.NI_name.errors %}
+                {{ form_l2vpn.NI_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.NI_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.NI_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.NI_mtu.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.NI_mtu.errors %}
+                {{ form_l2vpn.NI_mtu(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.NI_mtu.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.NI_mtu(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.NI_description.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l2vpn.NI_description.errors %}
+                {{ form_l2vpn.NI_description(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.NI_description.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.NI_description(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_NI_remote_system.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_NI_remote_system.errors %}
+                {{ form_l2vpn.Device_1_NI_remote_system(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_NI_remote_system.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_NI_remote_system(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_NI_remote_system.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_NI_remote_system.errors %}
+                {{ form_l2vpn.Device_2_NI_remote_system(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_NI_remote_system.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_NI_remote_system(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_NI_VC_ID.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_NI_VC_ID.errors %}
+                {{ form_l2vpn.Device_1_NI_VC_ID(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_NI_VC_ID.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_NI_VC_ID(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_NI_VC_ID.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_NI_VC_ID.errors %}
+                {{ form_l2vpn.Device_2_NI_VC_ID(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_NI_VC_ID.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_NI_VC_ID(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_NI_connection_point.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_NI_connection_point.errors %}
+                {{ form_l2vpn.Device_1_NI_connection_point(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_NI_connection_point.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_NI_connection_point(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_NI_connection_point.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_NI_connection_point.errors %}
+                {{ form_l2vpn.Device_2_NI_connection_point(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_NI_connection_point.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_NI_connection_point(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        
+        <h4>Interface Parameters</h4>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_IF_index.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_IF_index.errors %}
+                {{ form_l2vpn.Device_1_IF_index(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_IF_index.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_IF_index(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_IF_index.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_IF_index.errors %}
+                {{ form_l2vpn.Device_2_IF_index(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_IF_index.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_IF_index(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_IF_vlan_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_IF_vlan_id.errors %}
+                {{ form_l2vpn.Device_1_IF_vlan_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_IF_vlan_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_IF_vlan_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_IF_vlan_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_IF_vlan_id.errors %}
+                {{ form_l2vpn.Device_2_IF_vlan_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_IF_vlan_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_IF_vlan_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_IF_mtu.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_IF_mtu.errors %}
+                {{ form_l2vpn.Device_1_IF_mtu(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_IF_mtu.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_IF_mtu(class="form-control") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_IF_mtu.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_IF_mtu.errors %}
+                {{ form_l2vpn.Device_2_IF_mtu(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_IF_mtu.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_IF_mtu(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l2vpn.Device_1_IF_description.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_1_IF_description.errors %}
+                {{ form_l2vpn.Device_1_IF_description(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_1_IF_description.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_1_IF_description(class="form-control") }}
+                {% endif %}
+            </div>
+            {{ form_l2vpn.Device_2_IF_description.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l2vpn.Device_2_IF_description.errors %}
+                {{ form_l2vpn.Device_2_IF_description(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l2vpn.Device_2_IF_description.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l2vpn.Device_2_IF_description(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        {% endif %}
+        <button type="submit" class="btn btn-primary">
+            <i class="bi bi-plus-circle-fill"></i>
+            {{ submit_text }}
+        </button>
+        <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Cancel
+        </button>
+    </div>
+    </fieldset>
+</form>
+{% endblock %}
\ No newline at end of file
diff --git a/src/webui/service/templates/service/configure_L3VPN.html b/src/webui/service/templates/service/configure_L3VPN.html
new file mode 100644
index 0000000000000000000000000000000000000000..575eec10ad3042ea1ed154a5f21fb6811f4d4ed0
--- /dev/null
+++ b/src/webui/service/templates/service/configure_L3VPN.html
@@ -0,0 +1,510 @@
+<!--
+ Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+<h1>Add New Service [L3VPN]</h1>
+<form method="POST" action="{{ url_for('service.add_configure_L3VPN') }}">
+    <fieldset>
+        <div class="row mb-3">
+            {{ form_l3vpn.hidden_tag() }}
+        </div> 
+        {% if form_l3vpn.l3vpn_params is not none %}
+        <h3>Generic Service Parameters</h3>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.service_name.errors %}
+                {{ form_l3vpn.service_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_type.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.service_type.errors %}
+                {{ form_l3vpn.service_type(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_type.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_type(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_device_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.service_device_1.errors %}
+                {{ form_l3vpn.service_device_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_device_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_device_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.service_device_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.service_device_2.errors %}
+                {{ form_l3vpn.service_device_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_device_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_device_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_endpoint_1.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.service_endpoint_1.errors %}
+                {{ form_l3vpn.service_endpoint_1(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_endpoint_1.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_endpoint_1(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.service_endpoint_2.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.service_endpoint_2.errors %}
+                {{ form_l3vpn.service_endpoint_2(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_endpoint_2.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_endpoint_2(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <h3>Generic Service Constraints</h3>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_capacity.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.service_capacity.errors %}
+                {{ form_l3vpn.service_capacity(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_capacity.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_capacity(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_latency.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.service_latency.errors %}
+                {{ form_l3vpn.service_latency(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_latency.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_latency(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_availability.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.service_availability.errors %}
+                {{ form_l3vpn.service_availability(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_availability.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_availability(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.service_isolation.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.service_isolation.errors %}
+                {{ form_l3vpn.service_isolation(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.service_isolation.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.service_isolation(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        </br>
+        <h3>Specific Service Parameters</h3>
+        </br>
+        <h4>Network Instance Parameters</h4>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_name.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_name.errors %}
+                {{ form_l3vpn.NI_name(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_name.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_name(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_route_distinguisher.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_route_distinguisher.errors %}
+                {{ form_l3vpn.NI_route_distinguisher(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_route_distinguisher.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_route_distinguisher(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_protocol.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_protocol.errors %}
+                {{ form_l3vpn.NI_protocol(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_protocol.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_protocol(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_as.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_as.errors %}
+                {{ form_l3vpn.NI_as(class="form-control is-invalid", placeholder="Mandatory if BGP protocol is selected") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_as.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_as(class="form-control", placeholder="Mandatory if BGP protocol is selected") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_address_family.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_address_family.errors %}
+                {{ form_l3vpn.NI_address_family(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_address_family.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_address_family(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_default_import_policy.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_default_import_policy.errors %}
+                {{ form_l3vpn.NI_default_import_policy(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_default_import_policy.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_default_import_policy(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_import_policy.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_import_policy.errors %}
+                {{ form_l3vpn.NI_import_policy(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_import_policy.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_import_policy(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_export_policy.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_export_policy.errors %}
+                {{ form_l3vpn.NI_export_policy(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_export_policy.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_export_policy(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_router_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_router_id.errors %}
+                {{ form_l3vpn.NI_router_id(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_router_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_router_id(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.NI_description.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-10">
+                {% if form_l3vpn.NI_description.errors %}
+                {{ form_l3vpn.NI_description(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.NI_description.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.NI_description(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <h4>Interface Parameters</h4>
+        <div class="row mb-3">
+            {{ form_l3vpn.Device_1_IF_index.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_1_IF_index.errors %}
+                {{ form_l3vpn.Device_1_IF_index(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_1_IF_index.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_1_IF_index(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.Device_2_IF_index.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_2_IF_index.errors %}
+                {{ form_l3vpn.Device_2_IF_index(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_2_IF_index.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_2_IF_index(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.Device_1_IF_vlan_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_1_IF_vlan_id.errors %}
+                {{ form_l3vpn.Device_1_IF_vlan_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_1_IF_vlan_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_1_IF_vlan_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.Device_2_IF_vlan_id.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_2_IF_vlan_id.errors %}
+                {{ form_l3vpn.Device_2_IF_vlan_id(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_2_IF_vlan_id.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_2_IF_vlan_id(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.Device_1_IF_address_ip.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_1_IF_address_ip.errors %}
+                {{ form_l3vpn.Device_1_IF_address_ip(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_1_IF_address_ip.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_1_IF_address_ip(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.Device_2_IF_address_ip.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_2_IF_address_ip.errors %}
+                {{ form_l3vpn.Device_2_IF_address_ip(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_2_IF_address_ip.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_2_IF_address_ip(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.Device_1_IF_address_prefix.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_1_IF_address_prefix.errors %}
+                {{ form_l3vpn.Device_1_IF_address_prefix(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_1_IF_address_prefix.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_1_IF_address_prefix(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.Device_2_IF_address_prefix.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_2_IF_address_prefix.errors %}
+                {{ form_l3vpn.Device_2_IF_address_prefix(class="form-control is-invalid", placeholder="Mandatory") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_2_IF_address_prefix.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_2_IF_address_prefix(class="form-control", placeholder="Mandatory") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.Device_1_IF_mtu.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_1_IF_mtu.errors %}
+                {{ form_l3vpn.Device_1_IF_mtu(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_1_IF_mtu.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_1_IF_mtu(class="form-control") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.Device_2_IF_mtu.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_2_IF_mtu.errors %}
+                {{ form_l3vpn.Device_2_IF_mtu(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_2_IF_mtu.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_2_IF_mtu(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        <div class="row mb-3">
+            {{ form_l3vpn.Device_1_IF_description.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_1_IF_description.errors %}
+                {{ form_l3vpn.Device_1_IF_description(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_1_IF_description.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_1_IF_description(class="form-control") }}
+                {% endif %}
+            </div>
+            {{ form_l3vpn.Device_2_IF_description.label(class="col-sm-2 col-form-label") }}
+            <div class="col-sm-4">
+                {% if form_l3vpn.Device_2_IF_description.errors %}
+                {{ form_l3vpn.Device_2_IF_description(class="form-control is-invalid") }}
+                <div class="invalid-feedback">
+                    {% for error in form_l3vpn.Device_2_IF_description.errors %}
+                    <span>{{ error }}</span>
+                    {% endfor %}
+                </div>
+                {% else %}
+                {{ form_l3vpn.Device_2_IF_description(class="form-control") }}
+                {% endif %}
+            </div>
+        </div>
+        {% endif %}
+        <button type="submit" class="btn btn-primary">
+            <i class="bi bi-plus-circle-fill"></i>
+            {{ submit_text }}
+        </button>
+        <button type="button" class="btn btn-block btn-secondary" onclick="javascript: history.back()">
+            <i class="bi bi-box-arrow-in-left"></i>
+            Cancel
+        </button>
+    </div>
+    </fieldset>
+</form>
+{% endblock %}
\ No newline at end of file
diff --git a/src/webui/service/templates/service/detail.html b/src/webui/service/templates/service/detail.html
index 9c27bc99a106c96c352b4623d4c5bd91839c6726..ff2de8a3c60d8732d9bfdfe0cb361fdddee172f6 100644
--- a/src/webui/service/templates/service/detail.html
+++ b/src/webui/service/templates/service/detail.html
@@ -26,15 +26,8 @@
             Back to service list
         </button>
     </div>
-    <!--
+    
     <div class="col-sm-3">
-        <a id="update" class="btn btn-secondary" href="#">
-            <i class="bi bi-pencil-square"></i>
-            Update
-        </a>
-    </div>-->
-    <div class="col-sm-3">
-        <!-- <button type="button" class="btn btn-danger"><i class="bi bi-x-square"></i>Delete service</button> -->
         <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
             <i class="bi bi-x-square"></i>
             Delete service
@@ -224,6 +217,69 @@
             </td>
         </tr>
         {% endif %}
+        {% if config.WhichOneof('config_rule') == 'acl' %}
+        <tr>
+            <td>
+                {% if config.acl %}
+                    {% set endpoint_id = config.acl.endpoint_id %}
+                    {% set rule_set_name = config.acl.rule_set.name %}
+                    /device[{{ endpoint_id.device_id.device_uuid.uuid }}]/endpoint[{{ endpoint_id.endpoint_uuid.uuid }}]/acl_ruleset[{{ rule_set_name }}]
+                {% endif %}
+            </td>
+            <td>
+                <ul>
+                    {% if config.acl.rule_set.name %}
+                        <li><b>name: </b>{{ config.acl.rule_set.name }}</li>
+                    {% endif %}
+                    {% if config.acl.rule_set.type %}
+                        <li><b>type: </b>{{ type[config.acl.rule_set.type] }}</li>
+                    {% endif %}
+                    {% if config.acl.rule_set.description %}
+                        <li><b>description: </b>{{ config.acl.rule_set.description }}</li>
+                    {% endif %}
+                    {% if config.acl.rule_set.user_id %}
+                        <li><b>user_id: </b>{{ config.acl.rule_set.user_id }}</li>
+                    {% endif %}  
+                    {% for entry in config.acl.rule_set.entries %}
+                    {% if entry.description %}
+                        <li><b>entry {{ entry.sequence_id }} description: </b>{{ entry.description }}</li>
+                    {% endif %}
+                    {% if entry.match.protocol %}
+                        <li><b>entry {{ entry.sequence_id }} protocol: </b>{{ entry.match.protocol }}</li>
+                    {% endif %}
+                    {% if entry.match.dscp %}
+                        <li><b>entry {{ entry.sequence_id }} dscp:</b>{{ entry.match.dscp }}</li>
+                    {% endif %}
+                    {% if entry.match.src_address %}
+                        <li><b>entry {{ entry.sequence_id }} src_address: </b>{{ entry.match.src_address }}</li>
+                    {% endif %}
+                    {% if entry.match.dst_address %}
+                        <li><b>entry {{ entry.sequence_id }} dst_address: </b>{{ entry.match.dst_address }}</li>
+                    {% endif %}
+                    {% if entry.match.src_port %}
+                        <li><b>entry {{ entry.sequence_id }} src_port: </b>{{ entry.match.src_port }}</li>
+                    {% endif %}
+                    {% if entry.match.dst_port %}
+                        <li><b>entry {{ entry.sequence_id }} dst_port: </b>{{ entry.match.dst_port }}</li>
+                    {% endif %}
+                    {% if entry.match.start_mpls_label %}
+                        <li><b>entry {{ entry.sequence_id }} start mpls label: </b>{{ entry.match.start_mpls_label }}</li>
+                    {% endif %}
+                    {% if entry.match.end_mpls_label %}
+                        <li><b>entry {{ entry.sequence_id }} end mpls label: </b> {{ entry.match.end_mpls_label }}</li>
+                    {% endif %}
+                    {% if entry.action.forward_action %}
+                        <li><b>entry {{ entry.sequence_id }} forward_action: </b>{{ f_action[entry.action.forward_action] }}</li>
+                    {% endif %}
+                    {% if entry.action.log_action %}
+                        <li><b>entry {{ entry.sequence_id }} log_action: </b>{{l_action[entry.action.log_action] }}</li>
+                    {% endif %}
+                {% endfor %}
+
+                </ul>
+            </td>
+        </tr>
+        {% endif %}
         {% endfor %}
     </tbody>
 </table>
diff --git a/src/webui/service/templates/service/home.html b/src/webui/service/templates/service/home.html
index 00feaff59128dd026ab2bdb369229a9d0aaae805..14226b7dcde572e196465b1e59e3ddf44c4193d9 100644
--- a/src/webui/service/templates/service/home.html
+++ b/src/webui/service/templates/service/home.html
@@ -20,15 +20,13 @@
     <h1>Services</h1>
 
     <div class="row">
-        <!-- <div class="col">
-            <a href="{{ url_for('service.add') }}" class="btn btn-primary" style="margin-bottom: 10px;">
+        <div class="col">
+            <a href="{{ url_for('service.add_configure') }}" class="btn btn-primary" style="margin-bottom: 10px;"> 
                 <i class="bi bi-plus"></i>
                 Add New Service
             </a>
-        </div> -->
+        </div> 
 
-        <!-- Only display XR service addition button if there are XR constellations. Otherwise it might confuse
-             user, as other service types do not have GUI to add service yet. -->
         {% if "DEVICEDRIVER_XR" in active_drivers %}
             <div class="col">
                 <a href="{{ url_for('service.add_xr') }}" class="btn btn-primary" style="margin-bottom: 10px;">
@@ -41,17 +39,8 @@
         <div class="col">
             {{ services | length }} services found in context <i>{{ session['context_uuid'] }}</i>
         </div>
-        <!-- <div class="col">
-            <form>
-                <div class="input-group">
-                    <input type="text" aria-label="Search" placeholder="Search..." class="form-control"/>
-                    <button type="submit" class="btn btn-primary">Search</button>
-                  </div>
-            </form>
-        </div> -->
     </div>
     
-
     <table class="table table-striped table-hover">
         <thead>
           <tr>
@@ -68,9 +57,7 @@
                 {% for service in services %}
                 <tr>
                     <td>
-                        <!-- <a href="{{ url_for('service.detail', service_uuid=service.service_id.service_uuid.uuid) }}"> -->
                             {{ service.service_id.service_uuid.uuid }}
-                        <!-- </a> -->
                     </td>
                     <td>
                         {{ service.name }}